1. for range
- for-range其实是语法糖,内部调用还是for循环,初始化会拷贝带遍历的列表(如array,slice,map),然后每次遍历的
v都是对同一个元素的遍历赋值。 也就是说如果直接对v取地址,最终只会拿到一个地址,而对应的值就是最后遍历的那个元素所附给v的值。对应伪代码如下:
package mainimport "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]=3map[0]=3map[1]=3map[2]=3
修正
package mainimport "fmt"func main() {slice := []int{0, 1, 2, 3}myMap := make(map[int]*int)for index, value := range slice {num := valuemyMap[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]=2map[3]=3map[0]=0map[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 />```gotype Something struct {values []int}var s1 = Something{}var s2 = Something{[]int{}}fmt.Println(s1.values == nil)fmt.Println(s2.values == nil)--------truefalse
```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>#### 函数声明```gopackage mainimport "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)) // 12fmt.Println(len([]rune(str))) // 8}
如果有中文字符判断的话,需要转
计算机只能处理数字,如果想要处理文本需要转换为数字才能处理,早些时候,计算机在设计上采用8bit作为一个byte,一个byte表示的最大整数就是255,想表示更大的整数,就需要更多的byte。
len()函数是用来获取字符串的字节长度,rune一个值代表的就是一个Unicode字符,所以求rune切片的长度就是字符个数。因为在utf-8编码中,英文占1个字节,中文占3个字节,所以最终结果就是15和9。
