35

一等公民 Golang

 4 years ago
source link: https://www.tuicool.com/articles/3EzQNfy
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.

下载安装Go语言

https://golang.org/doc/install

https://golang.google.cn/dl/

安装IDE

Atom: https://atom.io + package:go-plus

若没有设置环境变量使用

Unix上默认为 $HOME/go

Windows上默认为 %USERPROFILE%/go

Mac 上 GOPATH 通过修改~/.bash_profile来设置

package main //包 ,表明代码所在的模块(包)
/*
    //只有25个关键字
    1.必须是main 包:package main
    2.必须是main 方法:func main()
    3. 文件名不一定是main.go
*/

/*
    退出返回值
    与其他主要编程语言的差异
    Go中main 函数不支持任何返回值
    通过os.Exit来返回状态
*/

import "fmt" //引入代码依赖
//功能实现
func main()  {
    
    fmt.Print("hello world")
     os.Exit(0)
}

直接运行 使用 go run hello.go

编译生成二进制 go build hello.go

package main
/*
获取命令行参数
与其他主要编程语言的差异
main 函数不支持传入参数
 func main(arg []string) 不支持 X 
 在程序中通过os.Args获取命令行参数
*/
import (
    "fmt"
    "os"
)

func main()  {
    fmt.Println(os.Args)
    if len(os.Args)>1 {
        fmt.Println("hello world cmd: ",os.Args[1])
    }
    fmt.Print("hello world")
    os.Exit(0)
}

编写测试程序

//源码文件以 _test结尾:xxx_test.go
//测试方法名以Test开头:func TestXXX(t *testing.T){ ... } 大写是包外可以访问
package try_test

import "testing"

func TestFirstTry(t *testing.T){
    t.Log("My First try!")
}
package fib

import (
    "fmt"
    "testing"
)
//全局变量声明
//var a int
func TestFibList(t *testing.T)  {
    //a = 1  //全局变量赋值
    //定义变量方法一
    //var a int = 1
    //var b int = 1
    //定义变量方法二
    //var(
    //  a int = 1
    //  b int = 1
    //)
    // 自动推断变量类型
    a := 1
    b := 1
    fmt.Print(a)
    for i :=0; i<5; i++ {
        // fmt.Print(" ", b)
        t.Log(" ", b)
        tmp := a
        a = b
        b = tmp + a
    }
    fmt.Println()

}
func TestSwap(t *testing.T) {
    a := 1
    b := 2
    // tmp := a
    // a = b
    // b = tmp
    // 对多个变量赋值
    a, b = b, a
    t.Log(a, b)
}
// 常量定义
// 与其他主要编程语言的差异
// 快速设置连续值
package constant_test

import "testing"

const (
    Monday = iota +1
    Tuesday
    Wednesday
    Thursday
    Friday
    Saturday
    Sunday
)
const (
    Open = 1 << iota
    Close
)
func TestConstantTry(t *testing.T)  {
    t.Log(Monday, Tuesday)
}
func TestConstantTryBin(t *testing.T)  {
    a := 7 //0111
    t.Log( a&Open == Open, a&Close == Close)
}
// 基本数据类型
bool
string
int int8 int16 int32 int64
uint uint8 uint16 uint32 uint64 uintptr
byte //alias for uint8
rune //alias for int32,represents a Unicode code point 
float32 float64
complex64 complex128
// 类型转换
// 与其他主要编程语言的差异
// 1.Go语言不允许隐式类型转换
// 2.别名和原有类型也不能进行隐式类型转换
package type_test

import "testing"
type MyInt int64 // 声明一个int64 的别名MyInt
func TestImplicit(t *testing.T) {
    var a int = 1
    var b int64
    b = int64(a) //显示转换
    // b = a //Err 不能隐式转换
    var c MyInt
    //c = b //Err 同类型的别名也不能隐式转换 严格
    c = MyInt(b)
    t.Log(a, b, c)
}
//类型的预定义值
1.math.MaxInt64
2.math.MaxFloat64
3.math.MaxUint32
//指针类型
与其他主要编程语言的差异
1.不支持指针运算
2.string是值类型,其默认的初始化值为空字符串,而不是nil
package type_test

import (
    "testing"
)
type MyInt int64 // 声明一个int64 的别名MyInt
func TestImplicit(t *testing.T) {
    var a int = 1
    var b int64
    b = int64(a) //显示转换
    // b = a //Err 不能隐式转换
    var c MyInt
    //c = b //Err 同类型的别名也不能隐式转换 严格
    c = MyInt(b)
    t.Log(a, b, c)
}

func TestPoint(t *testing.T) {
    a :=1
    aPtr := &a
    // aPtr = aPtr + 1 //Err 不支持运算
    t.Log(a, aPtr)
    t.Logf(" %T %T", a, aPtr)
}
func TestString(t *testing.T) {
    var s string
    //string是值类型默认是空字符串
    t.Log("*" + s +"*")
    t.Log(len(s))
    if s == ""{
        t.Log("字符串是空")
    }
}
  • 算术运算符
运算符 描述 示例 + 相加 A := 10 B := 10 ==> A + B 输出结果 20 - 相减 A - B 输出结果 0 * 相乘 A * B 输出结果 100 / 相除 B / A 输出结果 1 % 求余 B % A 输出结果 0 ++ 自增 A++ 输出结果 11 -- 自减 A-- 输出结果 9

Go语言没有前置的 ++, --;(++a) Err

  • 比较运算符

    运算符 描述 示例 == 检查两个值是否相等,如果相等返回True,否则返回False !> 检查两个值是否不相等,如果不相等返回True ,否则返回False > 检查左边值是否大于右边值,如果是返回True,否则返回False < 检查左边值是否小于右边值,如果是返回True 否则返回False >= 检查左边值是否大于等于右边值,如果是返回True 否则返回False <= 检查左边值是否小于等于右边值,如果是返回True 否则返回False
  • 用 == 比较数组

    • 相同维数且含有相同个数元素的数组才可以比较

    • 每个元素都相同才相等

  • 逻辑运算符 ( && 、 || 、!)

  • 位运算符 (&、 | 、^ 、<< 、>>)

    位运算符
    与其他主要编程语言的差异
    &^ 按位清零
    1 &^ 0 -- 1
    1 &^ 1 -- 0
    0 &^ 1 -- 0
    0 &^ 0 -- 0
    package operator_test
    
    import (
      "fmt"
      "testing"
    )
    
    func TestCompareArray(t *testing.T)  {
      a := [...]int{1,2,3,4}
      b := [...]int{1,2,3,4}
      //c := [...]int{1,2,3,4,5}
      //
      t.Log(a == b)
      //t.Log(c)
      //t.Log( a == c)
    }
    /*
    循环
    Go 语言仅支持循环关键字 for
    for j :=7; j <=9; j++
    */
    func TestForLoop(t *testing.T)  {
      for j := 0; j <= 10; j++ {
          t.Log("执行第" ,j , "次")
      }
    }
    /*
    while 条件循环
    while (n < 5)
    */
    func TestWhileLoop(t *testing.T){
      n := 0
      for n < 5 {
          n++
          fmt.Println(n)
      }
    }
    /*
    while 条件循环
    while (true)
    */
    func TestForLoop(t *testing.T){
      //n := 0
      //for {
      //  n++
      //  fmt.Print("死循环")
      //}
    }

if 条件

与其他主要编程语言差异

1.condition表达式结果必须为bool 布尔值

2.支持变量赋值

if var declaration; condition{

​ //code

}

switch 条件

1.条件表达式不限制为常量或者整数

2.单个case中,可以出现多个结果选项,使用逗号分隔

3.与C语言等规则相反,Go语言不需要用break 来明确退出一个case;

4.可以不设定switch之后的条件表达式,在这种情况下,整个switch结构与多个if else 的逻辑作用等同

switch os := runtime.GOOS;os{

case "xxx":

default:

}

func TestSwitchMultiCase(t *testing.T) {
    for i :=0; i <5; i++  {
        switch i {
        case 0, 2:
            t.Log("Even")
        case 1,3:
            t.Log("Odd")
        default:
            t.Log("it is not 0-3")


        }
    }
}
func TestSwitchCaseCondition(t *testing.T) {
    for i :=0; i <5; i++  {
        switch {
        case i%2 == 0:
            t.Log("Even")
        case i%2 == 1:
            t.Log("Odd")
        default:
            t.Log("不会走这个分支")


        }
    }
}
package slice_test

import "testing"

func TestSliceInit(t *testing.T)  {
    var s0 []int
    t.Log(len(s0), cap(s0))
    s0 = append(s0, 1)
    t.Log(len(s0), cap(s0))
    //方式二
    s1 := []int{1, 2, 3, 4}
    t.Log(len(s1), cap(s1))
    //方式三
    //[]type ,len,cap 其中len 个元素会被初始化为默认零值,未初始化元素不可以访问
    s2 := make([]int, 3, 5)
    t.Log(len(s2), cap(s2))
    s2 = append(s2, 1)
    t.Log(s2[0], s2[1],s2[2] ,s2[3])
}
/**
    切片共享存储结构
*/
func TestSliceGrowing(t *testing.T) {
    s := []int{}
    for i := 0; i < 10; i++  {
        s = append(s, i)
        t.Log(len(s),cap(s))
    }
}
func TestSliceShareMemory(t *testing.T) {
    year := []string{"Jan", "Feb", "Mar", "Apr", "May","Jun", "Jul","Aug","Sep","Oct","Nov","Dec"}
    Q2 := year[3:6]
    t.Log(Q2, len(Q2),cap(Q2))
    summer := year[5 :8]
    t.Log(summer,len(summer), cap(summer))
    summer[0] = "UnKnow"
    t.Log(Q2)
    t.Log(year)
}
/*
数组 vs 切片
1.容量是否可伸缩
2.是否可以进行比较
结论:
数组不可伸缩 ,可比较
切片可伸缩,不可比较
*/
package string_test

import (
    "testing"
    "unsafe"
)

/*
字符串
与其他主要编程语言的差异
1.string 是数据类型,不是引用或指针类型
2. string是只读 byte slice ,len 函数是它所包含的byte数
3.string的byte数组可以存放任何数据
*/
func TestString(t *testing.T){
    var s string
    t.Log(s) //初始化默认零值""
    s = "hello"
    t.Log(len(s))
    //s[1] = "3" //string是不可变byte slice
    s ="\347\216\213" //可以存储任何二进制数据
    t.Log(s)
    s = "中China"
    t.Log(len(s)) // byte数
    c :=[]rune(s)
    t.Log("rune size:",unsafe.Sizeof(c[0]))
    t.Logf("中 Unicode %x", c[0])
    t.Logf("中 UTF %x",s)

}
package map_and_factory_test

import (
    "testing"
)

/*
Map 与工厂模式
Map的value 可以是一个方法
与Go的 Dock type接口方式一起,可以方便的实现单一方法对象的工厂模式
*/
func TestMapWithFunValue(t *testing.T) {
    m := map[int]func(op  int)int{}
    m[1] = func(op int) int { return op }
    m[2] = func(op int) int { return op * op }
    m[3] = func(op int) int { return op * op * op }
    t.Log(m[1](1), m[2](2), m[3](2))
}
/*
实现 Set
Go 的内置集合中没有Set的实现 ,可以map[type]bool
1.元素的唯一性
2.基本操作
    1)添加元素
    2)判断元素是否存在
    3)删除元素
    4)元素个数
*/
func TestMapForSet(t *testing.T) {
    mySet := map[int]bool{}
    mySet[1] = true
    n := 3
    if mySet[n] {
        t.Logf("%d  is existing", n)
    } else {
        t.Logf(" %d is not existing", n)
    }
    t.Log(len(mySet))
    delete(mySet,1)
    t.Log(len(mySet))
    n = 1
    if mySet[n] {
        t.Logf("%d  is existing", n)
    } else {
        t.Logf(" %d is not existing", n)
    }
}
package string_test

import (
    "strconv"
    "strings"
    "testing"
)

func TestStringFn(t *testing.T)  {
    t.Log("test")
    s :="A, B, C"
    parts := strings.Split(s, ",")
    for _, part := range parts{
        t.Log(part)
    }
    t.Log(strings.Join(parts, "-"))

}

func TestStringToNum(t *testing.T)  {
    s :=strconv.Itoa(10)
    t.Log("str " + s)
    if i, err :=strconv.Atoi("10");err == nil {
        t.Log(10 + i)
    }

}
package string_test

import (
    "testing"
    "unsafe"
)

/*
字符串
与其他主要编程语言的差异
1.string 是数据类型,不是引用或指针类型
2. string是只读 byte slice ,len 函数是它所包含的byte数
3.string的byte数组可以存放任何数据
*/
func TestString(t *testing.T){
    var s string
    t.Log(s) //初始化默认零值""
    s = "hello"
    t.Log(len(s))
    //s[1] = "3" //string是不可变byte slice
    s = "\347\216\213"//可以存储任何二进制数据
    t.Log(s)
    s = "中"
    t.Log(len(s)) // byte数
    c :=[]rune(s)
    t.Log("rune size:",unsafe.Sizeof(c[0]))
    t.Logf("中 Unicode %x", c[0])
    t.Logf("中 UTF %x",s)

}
/*
strings 包 https://golang.org/pkg/strings/
strconv 包 https://golang.org/pkg/strconv/
*/
func TestStringToRune(t *testing.T) {
    s := "中华人民共和国"
    for _, c := range  s {
        t.Logf(" %[1]c %[1]d",c)
    }
}

About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK