Golang初入编程-踩坑笔记(1)

  1. 一定要自己动手写,不然使用的时候可能连等号的位置都搞不清楚

  2. 该语言没有面向对象的概念,什么函数传什么参数返回什么值自己要多练习

  3. i++属于独立语句,不能和其他语句写到一起,自己占一行

  4. 以下东东需要初始化(开辟空间),包括切片,指针,map(数组声明后,会填充默认值)

  5. 函数可返回多个

  6. 使用:=声明并赋值,函数外不行

  7. const常量(静态变量)关键字,内部可使用iota作为计数器赋值

  8. iota只能在常量的表达式中使用

  9. 每次const出现都会使iota归零

  10. iota按行自增,所以同一行的iota是一样的值

  11. 可以使用 _ 来接收不要的参数,可以用来跳过iota的值,或者接收函数的返回值时用来占位

  12. 切片是引用类型,底层数组改变,切片也会变

  13. append()只有两个参数,第一个是被加的切片,第二个是追加的切片,(返回的也是切片),其实就是俩切片相加

  14. append()第二个参数要加 ... 才是每个值,这是单个添加的特殊写法

  15. 用于切片的append函数(追加)需要接收,注意:根据需求,该函数会改变底层数组

    testSlice = append(testSlice, 0)
    
  16. 指针开辟空间要用new关键字,其他数组,mapchan都需要用makemake内部不传入什么实例,没有实例的概念,要传入类型,容量,长度等)

  17. 但是一般不用new([]int)来搞指针,为啥要自己建一个空指针呢?空指针会直接报错!应该使用取地址来操作

    pointer = &a
    
  18. for k,v := range myArray{}注意:=位置

  19. copy(切片|数组,切片)被复制的只能是切片,输出文档上说是切片,可是我实测数组也行,可能是引用类型的原因。

  20. copy输出的也是切片!返回的是长度

func main() {
	slice1 := []int{1, 2, 3, 4, 5}
	slice2 := []int{5, 4, 3}
	copy(slice2, slice1) // 只会复制slice1的前3个元素到slice2中
	fmt.Println(slice1)//[1 2 3 4 5]
	fmt.Println(slice2)//[1 2 3]
	slice1 = []int{1, 2, 3, 4, 5}
	slice2 = []int{5, 4, 3}
	lenth := copy(slice1, slice2) // 只会复制slice2的3个元素到slice1的前3个位置
	fmt.Println(slice1)//[5 4 3 4 5]
	fmt.Println(slice2)//[5 4 3]
	fmt.Println(lenth)//3
}
  1. 集合直接make也行,反正都要初始化
  2. 函数作为接收者,尽量用指针
  3. 同理,参数也尽量用指针
  4. 函数调用会复制参数,所以不使用指针不能改变结构体(对象)的值
  5. 对象/结构体调用函数时,不用管指针还是取地址*s,&s,反正go都会自动转换,关键是函数要把接收者写成指针形式。
  6. 注意go对象自动转换不能套环,嵌套无效,案例如下
type Student struct {
   age int8
   name string
}
type StudentPoint *Student
 
func (Student) sayHello() {  //省略receiver 的参数参数名字
   fmt.Println("hello world")
}
 
func (s Student) showName() { 
   fmt.Println(s.name)
}
 
func (s * Student) setName(newName string) {
   s.name = newName
}
// Error:接受者(receiver)为指针类型
func (s StudentPoint) showName2(){ // Error:接受者(receiver)为指针类型
   fmt.Println(s.name)
}
 
s := Student{}
s.setName("dq") 
//go会自动转为 (&s).setName("dq")
 
var s2 = &s
s2.showName() 
//o会自动转为 (*s2).showName()
  1. 在结构体中嵌入指针变量,要注意赋值,不然新建一个带有指针的对象,内部指针未赋值,会panic,空指针报错。初始化结构体,并不会给一个指针开空间。
type Person struct {
   age  int8
   name string
}
func (s Person) showName() {
   fmt.Println(s.name)
}
func (s *Person) setName(newName string) {
   s.name = newName
}
type Student1 struct {
   Person //Student1包含了Person,那么Student1对应的value和pointer包含Person
}
type Student2 struct {
   *Person
} 
// 内嵌类型 Persion默认值为 Person{age:0, name:""}
s1 := Student1{}
s1.setName("student1_01") // ok
s1.showName()
// 内嵌类型 *Persion默认值为 nil
s2 := &Student2{}
s2.setName("student1_02") //Error,由于目前内嵌类型的值为nil,会触发报错
s2.showName()
// 给嵌入类型一个复制,就ok了
s3 := &Student2{Person:&Person{age:3, name:"s3"}}
//s3 := &Student2{&Person{age:3, name:"s3"}} 和上一行等价
s3.showName()
  1. for i, v := range arri,v都是复制的,并且只有一个,所以直接取地址,或者希望改变i,v来改变源数组,都是不行的。直接取地址保存的是复制的v的地址,其内容就只是循环结束后的内容,每次循环内容都会被改变,指针不变。
func main() {
	arr := []int{1, 2, 3}
	myMap := make(map[int]*int)
	for i, v := range arr {
		myMap[i] = &v	//错了,v的地址永远不变
	}
	for _, v := range myMap {
		fmt.Println(*v) 	//输出3,3,3
	}
}
©️2020 CSDN 皮肤主题: 深蓝海洋 设计师:CSDN官方博客 返回首页