Closed opskumu closed 5 years ago
基础类型
、复合类型
、引用类型
和 接口类型
In Go, a string is in effect a read-only slice of bytes.
const s = "世界"
fmt.Println(len(s)) // 输出结果为 6 表示字符串 s 占用 6 个字节,一个中文占用 3 个字节
fmt.Println(len([]rune(s))) // 输出结果为 2 表示字符串 s 转换成 rune 之后占用 2 个 rune 字符码
const s = "世界"
for i, v := range s {
fmt.Printf("%#U starts at byte position %d\n", v, i)
}
%#U, which shows the code point's Unicode value and its printed representation.
运行结果
U+4E16 '世' starts at byte position 0
U+754C '界' starts at byte position 3
字符串遍历
for i := 0; i < xx; i++
这种方式是一个字节一个字节遍历for i, v := range xx
这种方式是遍历字符串的 runerune
(int32
类型别名)
byte
(uint8
类型别名)
Go 的字符串是 UTF-8
编码的,UTF8 编码使用 1 到 4 个 字节来表示每个 Unicode 码点
反引号 `` 创建原生的字符串字面量,不支持任何转义
...
省略号,则表示数组的长度是根据初始化值的个数来计算q := [...]int{1, 2, 3}
symbol := [...]string{0: "$", 3: "¥"} // 数组中指定了第一个和第四个索引值,未指定的自动取空字符串
指针
、长度
和 容量
。指针指向第一个 slice 元素对应的底层数组元素的地址,要注意的是 slice 的第一个元素并不一定就是数组的第一个元素。长度对应 slice 中元素的数目; 长度不能超过容量,容量一般是从 slice 的开始位置到底层数据的结尾位置。内置的 len
和 cap
函数分别返回 slice 的长度和容量nil
比较package main
import "fmt"
func array(a [4]string) [4]string {
a[0] = "That"
return a
}
func slice(s []string) []string {
s[0] = "That"
return s
}
func main() {
a := [4]string{"This", "is", "a", "test"}
s := []string{"This", "is", "a", "test"}
array(a)
slice(s)
fmt.Println(a) // 作用域问题,此处数组不会改变
fmt.Println(s) // 因为 slice 元素本身是指针,所以此处 “This” 会被替换成 "That"
}
输出结果:
[This is a test]
[That is a test]
无序
的 key/value
对的集合,在 Go 中,一个 map 就是一个哈希表的引用type Circle struct {
Point
Radius int
}
type Wheel struct {
Circle
Spokes int
}
得意于匿名嵌入的特性,我们可以直接访问叶子属性而不需要给出完整的路径:
var w Wheel w.X = 8
w.Y = 8 w.Radius = 5 w.Spokes = 20
// equivalent to w.Circle.Point.X = 8
// equivalent to w.Circle.Point.Y = 8
// equivalent to w.Circle.Radius = 5
%v
参数包含的 #
副词,它表示用和 Go 语言类似的语法打印值。对于结构体类型来说,将包含每个成员的名字w = Wheel{Circle{Point{8, 8}, 5}, 20}
w = Wheel{
Circle: Circle{
Point: Point{X: 8, Y: 8},
Radius: 5,
},
Spokes: 20, // NOTE: trailing comma necessary here (and at Radius) }
fmt.Printf("%#v\n", w)
// Output:
// Wheel{Circle:Circle{Point:Point{X:8, Y:8}, Radius:5}, Spokes:20}
最后一个参数
类型之前加上省略符号 ...
,这表示该函数会接收任意数量的该类型参数
...int
型参数的行为看起来很像切片类型,但实际上,可变参数函数和以切片作为参数的函数是不同的func f(...int) {}
func g([]int) {}
fmt.Printf("%T\n", f) // "func(...int)"
fmt.Printf("%T\n", g) // "func([]int)"
大写首字母
的标识符会从定义它们的包中被导出,小写字母的则不会。这种限制包内成员的方式同样适用于结构体字段或者一个类型的方法errors.New
函数是非常稀少的,因为有一个方便的封装函数 fmt.Errorf
,它还会处理字符串格式化使用内置的 make 函数,我们可以创建一个 channel:
ch := make(chan int) // ch has type 'chan int'
cap
可以获取 channel 内部缓存容量,内置函数 len
可以获取内部缓存队列中有效元素的个数关于性能问题还需要进一步理解!!!
_
来重命名导入的包。像往常一样,下划线 _
为空白标识符,并不能被访问import _ "image/png" // register PNG decoder
《go programming language》笔记摘要
二、程序结构
命名
小写
驼峰式
命名,当名字有几个单词组成时优先使用大小写
分隔,而非下划线声明
var
、const
、type
、func