1. for range
- for-range其实是语法糖,内部调用还是for循环,初始化会拷贝带遍历的列表(如array,slice,map),然后每次遍历的
v
都是对同一个元素的遍历赋值。 也就是说如果直接对v
取地址,最终只会拿到一个地址,而对应的值就是最后遍历的那个元素所附给v
的值。对应伪代码如下:
package main
import "fmt"
func main() {
slice := []int{0, 1, 2, 3}
myMap := make(map[int]*int)
for index, value := range slice {
myMap[index] = &value
}
prtMap(myMap)
}
func prtMap(myMap map[int]*int) {
for key, value := range myMap {
fmt.Printf("map[%v]=%v\n", key, *value)
}
}
输出
map[3]=3
map[0]=3
map[1]=3
map[2]=3
修正
package main
import "fmt"
func main() {
slice := []int{0, 1, 2, 3}
myMap := make(map[int]*int)
for index, value := range slice {
num := value
myMap[index] = &num // &slice[index] 也可以,去掉value
}
prtMap(myMap)
}
func prtMap(myMap map[int]*int) {
for key, value := range myMap {
fmt.Printf("map[%v]=%v\n", key, *value)
}
}
输出
map[2]=2
map[3]=3
map[0]=0
map[1]=1
2. 遍历会停止么
v := []int{1, 2, 3}
for i := range v {
v = append(v, i)
}
【会】,因为遍历前对v
做了拷贝,所以期间对原来v
的修改不会反映到遍历中
3. 对大数组这样遍历有啥问题?
//假设值都为1,这里只赋值3个
var arr = [102400]int{1, 1, 1}
for i, n := range arr {
//just ignore i and n for simplify the example
_ = i
_ = n
}
【有问题】!遍历前的拷贝对内存是极大浪费啊 怎么优化?有两种 - 对数组取地址遍历 for i, n := range &arr - 对数组做切片引用 for i, n := range arr[:]
4. 零切片和nil切片
```go package main
import “fmt”
func main() { var s1 []int // nil 切片 var s2 = []int{}
fmt.Println(s1 == nil)
fmt.Println(s2 == nil)
fmt.Printf("%#v\n", s1)
fmt.Printf("%#v\n", s2)
}
true false []int(nil) []int{}
2. <br />
```go
type Something struct {
values []int
}
var s1 = Something{}
var s2 = Something{[]int{}}
fmt.Println(s1.values == nil)
fmt.Println(s2.values == nil)
--------
true
false
```go type Something struct { Values []int }
var s1 = Something{} var s2 = Something{[]int{}} bs1, := json.Marshal(s1) bs2, := json.Marshal(s2) fmt.Println(string(bs1)) fmt.Println(string(bs2))
{“Values”:null} {“Values”:[]}
<a name="K3mUx"></a>
#### 5. Add函数一定要在Wait函数执行前执行
<a name="IofSg"></a>
#### 函数声明
```go
package main
import "fmt"
func DeferFunc1(i int) (t int) {
fmt.Println("t = ", t)
return 2
}
func main() {
DeferFunc11(10)
}
t = 0
证明,只要声明函数的返回值变量名称,就会在函数初始化时候为之赋值为0,而且在函数体作用域可见。
6 Go语言字符串的字节长度和字符个数
func main() {
str := "Golang罗尔"
fmt.Println(len(str)) // 12
fmt.Println(len([]rune(str))) // 8
}
如果有中文字符判断的话,需要转
计算机只能处理数字,如果想要处理文本需要转换为数字才能处理,早些时候,计算机在设计上采用8bit作为一个byte,一个byte表示的最大整数就是255,想表示更大的整数,就需要更多的byte。
len()函数是用来获取字符串的字节长度,rune一个值代表的就是一个Unicode字符,所以求rune切片的长度就是字符个数。因为在utf-8编码中,英文占1个字节,中文占3个字节,所以最终结果就是15和9。