自学go中(二)

自学go中(二)

类型

var t interface{}
t = functionOfSomeType()
switch t := t.(type) {
default:
    fmt.Printf("unexpected type %T", t)       // %T 输出 t 是什么类型
case bool:
    fmt.Printf("boolean %t\n", t)             // t 是 bool 类型
case int:
    fmt.Printf("integer %d\n", t)             // t 是 int 类型
case *bool:
    fmt.Printf("pointer to boolean %t\n", *t) // t 是 *bool 类型
case *int:
    fmt.Printf("pointer to integer %d\n", *t) // t 是 *int 类型
}

byte,[]byte和string类型

defer(重点理解和使用类型)

推迟执行函数,多用于资源关闭(比如可能出现错误,等异常情况返回的时候)

数据

初始化,分配

new分配方法

  1. 分配的结果是一个指向类型为T的内存地址空间
  2. 返回类型为*T
  3. 属性会被分配为 “零值”
p := new(SyncedBuffer)  // type *SyncedBuffer
var v SyncedBuffer      // type  SyncedBuffer

构造函数

零值分配有时候可能不太好,需要一个构造函数一般构造函数都是使用NewStrcut的方式创建。
或者可以再配合上复合字面来初始化

make分配

make只用来创建 切片,映射,和信道,返回的类型都为T,如果明确知道需要的是 *T,就要使用new方式或者构造函数以及复合字面产生指针类型的结构体。

make一个切片,切片这个结构里面保存了三个内容(指向数组的指针,长度,和容量)。

数组

数组的含义非常清晰,用法也不多说。主要来说下GO中数组与C的区别。

  1. 数组是值,在C中数组是指针。所以在函数中使用数组是直接传输数组的副本的
  2. 数组的大小是其类型的一部分,所有[10]int 和[20]int的类型是不同的。所以如果在函数使用的过程中需要传递一个数组或者一个数组的指针那么一定要明确数组的大小

所以一般都使用切片

切片

使用非常频繁,只需要熟悉几个内置函数

  1. append

  2. 取得其第1个到第4个 slice[0:4]

二维数组>二维切片

二维切片的make方法和一维没有什么太大的区别

映射

只要支持相等性判断的类型都可以使用映射(切片没有实现

  1. 若试图通过映射中不存在的键来取值,就会返回与该映射中项的类型对应的零值,也就是说如果value的T是bool,那么key不存在情况下就会返回对应默认的零值。但是有些时候,key存在对应的value就是零值,那么怎么办。所以映射访问会返回 value,ok = map[key]如果ok为true就表示存在。

  2. 删除,使用delete

常量

常量只能是数字、字符(符文)、字符串或布尔值。由于编译时的限制, 定义它们的表达式必须也是可被编译器求值的常量表达式。例如 1<<3 就是一个常量表达式,而 math.Sin(math.Pi/4) 则不是,因为对 math.Sin 的函数调用在运行时才会发生。

总体来说:常量必须是在编译的时候就能确定的

type ByteSize float64

const (
    // 通过赋予空白标识符来忽略第一个值
    _           = iota // ignore first value by assigning to blank identifier
    KB ByteSize = 1 << (10 * iota)
    MB
    GB
    TB
    PB
    EB
    ZB
    YB
)

变量

变量的初始化与常量类似,但其初始值也可以是在运行时才被计算的一般表达式。

init

所有变量声明都通过它们的初始化器求值后 init 才会被调用, 而那些 init 只有在所有已导入的包都被初始化后才会被求值

问题

  1. string与byte类型

  2. nil问题

你可能感兴趣的:(自学go中(二))