Go foundation: Pointer, Map, structure

pointer

Go language function parameters are passed to copy values , when we when you want to modify a variable , we can create a pointer variable that points to the address of a variable .

Different from the C / C ++ in the pointer, Go language pointer can not be shifted and operation are safe pointer .

Go wants to understand the language of pointers you need to know three concepts: pointer address, pointer types, and pointer values .

And pointer type pointer address

Go language pointer operation is very simple, only need to remember two symbols: &(address), and *(the address value) .

Each variable at run time has an address, the address represents the variable location in memory. Go languages use an ampersand in front of the variable of variables "take the address" operation.

Take the pointer variable syntax is as follows:

ptr := &v    // v的类型为T

among them:

v:代表被取地址的变量,类型为T
ptr:用于接收地址的变量,ptr的类型就为*T,称做T的指针类型。*代表指针。

func main() {
    a := 10
    b := &a
    fmt.Printf("a:%d ptr:%p\n", a, &a) // a:10 ptr:0xc00001a078
    fmt.Printf("b:%p type:%T\n", b, b) // b:0xc00001a078 type:*int
    fmt.Println(&b)                    // 0xc00000e018
}

Pointer Value

 And address-value operator & operator *is a pair of complementary operator, &fetch address, *the address pointed to by the address value extracted.

Variables, characteristics and the relationship between the address pointers, pointer variable, taking the address, the value is as follows:

1. fetch address variable (&) operation can be obtained pointer variable this variable.
2. The value of the pointer variable is a pointer address.
3. The value of the pointer variable (*) operation, the value of the original variable may get a pointer variable points.

  • When the variable is not assigned to any of a pointer is defined, its value is nil

Pointer variable initialization

func main() {
    var a *int
    *a = 100
    fmt.Println(*a)

    var b map[string]int
    b["测试"] = 100
    fmt.Println(b)
}


// panic: runtime error: invalid memory address or nil pointer dereference
//[signal 0xc0000005 code=0x1 addr=0x0 pc=0x49a7ca]

The implementation of the code above will lead to panic, why?

  •  In the Go language for a reference type variable, we must not only declare it when in use, but also to allocate memory space for it , otherwise we have no way to store value.
  • As for the value of the type of statement you do not need to allocate memory space, because they have a good default allocated memory space when it was declared .

 Go and make new languages are two built-in functions , mainly used to allocate memory

func new(Type) *Type
func make(t Type, size ...IntegerType) Type

1. Both are used for memory allocation.
2. the make only for initializing the slice, map and channel, or the return of the three types of reference itself ;
3. for the new type of memory allocation, and memory type corresponding to the value zero value returned is a pointer type pointer.

Map

Go language map is a reference type, must be initialized before use, is a disorder of the data structure of key-value-based

func main() {
    scoreMap := make(map[string]int, 8)
    scoreMap["张三"] = 90
    scoreMap["小明"] = 100
    fmt.Println(scoreMap)
    fmt.Println(scoreMap["小明"])
    fmt.Printf("type of a:%T\n", scoreMap)
}
map also supports filling element when it was declared

Go language used for range traverse map

func main() {
    scoreMap := make(map[string]int)
    scoreMap["张三"] = 90
    scoreMap["小明"] = 100
    scoreMap["王五"] = 60
    for k, v := range scoreMap {
        fmt.Println(k, v)
    }
}

Traversal order specified map

 

func main() {
    rand.Seed(time.Now().UnixNano()) //初始化随机数种子

    var scoreMap = make(map[string]int, 200)

    for i := 0; i < 100; i++ {
        key := fmt.Sprintf("stu%02d", i) //生成stu开头的字符串
        value := rand.Intn(100)          //生成0~99的随机整数
        scoreMap[key] = value
    }
    //取出map中的所有key存入切片keys
    var keys = make([]string, 0, 200)
    for key := range scoreMap {
        keys = append(keys, key)
    }
    //对切片进行排序
    sort.Strings(keys)
    //按照排序后的key遍历map
    for _, key := range keys {
        fmt.Println(key, scoreMap[key])
    }
}

Type of map elements sliced

func main() {
    var mapSlice = make([]map[string]string, 3)
    for index, value := range mapSlice {
        fmt.Printf("index:%d value:%v\n", index, value)
    }
    fmt.Println("after init")
    // 对切片中的map元素进行初始化
    mapSlice[0] = make(map[string]string, 10)
    mapSlice[0]["name"] = "王五"
    mapSlice[0]["password"] = "123456"
    mapSlice[0]["address"] = "红旗大街"
    for index, value := range mapSlice {
        fmt.Printf("index:%d value:%v\n", index, value)
    }
}

Slice type values ​​map

func main() {
    var sliceMap = make(map[string][]string, 3)
    fmt.Println(sliceMap)
    fmt.Println("after init")
    key := "中国"
    value, ok := sliceMap[key]
    if !ok {
        value = make([]string, 0, 2)
    }
    value = append(value, "北京", "上海")
    sliceMap[key] = value
    fmt.Println(sliceMap)
}

Structure 

Go language has no concept of "class" does not support the "class" of inheritance and other object-oriented concepts .

Go through the language embedded in the structure together with the interface than the object-oriented higher expandability and flexibility.

The difference between type definitions and type aliases

Type alias type defined surface difference of only one equal sign

//类型定义
type NewInt int

//类型别名
type MyInt = int

func main() {
    var a NewInt
    var b MyInt

    fmt.Printf("type of a:%T\n", a) //type of a:main.NewInt
    fmt.Printf("type of b:%T\n", b) //type of b:int
}

struct

Go to object-oriented languages ​​by struct

Taking the address structure

type student struct {
    name string
    age  int
}

func main() {
    m := make(map[string]*student)
    stus := []student{
        {name: "pprof.cn", age: 18},
        {name: "测试", age: 23},
        {name: "博客", age: 28},
    }

    for _, stu := range stus {
        m[stu.name] = &stu
    }
    for k, v := range m {
        fmt.Println(k, "=>", v.name)
    }
}

No constructor structure, can achieve their own

Go structure of language has no constructor, we own realization. For example, the code below on the realization of a person's constructor. Struct type is a value because, if the structure is more complex, copies the value of the performance overhead will be relatively large, so that the constructor returns a pointer to the structure type

func newPerson(name, city string, age int8) *person {
    return &person{
        name: name,
        city: city,
        age:  age,
    }
}

Call the constructor

p9 := newPerson("pprof.cn", "测试", 90)
fmt.Printf("%#v\n", p9)

Methods & Recipients

Go语言中的方法(Method)是一种作用于特定类型变量的函数。这种特定类型变量叫做接收者(Receiver)。接收者的概念就类似于其他语言中的this或者 self。

方法的定义格式如下:

    func (接收者变量 接收者类型) 方法名(参数列表) (返回参数) {
        函数体
    }

其中,

    1.接收者变量:接收者中的参数变量名在命名时,官方建议使用接收者类型名的第一个小写字母,而不是self、this之类的命名。例 如,Person类型的接收者变量应该命名为 p,Connector类型的接收者变量应该命名为c等。
    2.接收者类型:接收者类型和参数类似,可以是指针类型和非指针类型。
    3.方法名、参数列表、返回参数:具体格式与函数定义相同。

举个例子:

//Person 结构体
type Person struct {
    name string
    age  int8
}

//NewPerson 构造函数
func NewPerson(name string, age int8) *Person {
    return &Person{
        name: name,
        age:  age,
    }
}

//Dream Person做梦的方法
func (p Person) Dream() {
    fmt.Printf("%s的梦想是学好Go语言!\n", p.name)
}

func main() {
    p1 := NewPerson("测试", 25)
    p1.Dream()
}

方法与函数的区别是,函数不属于任何类型,方法属于特定的类型。

结构体的“继承”

Go语言中使用结构体也可以实现其他编程语言中面向对象的继承。

//Animal 动物
type Animal struct {
    name string
}

func (a *Animal) move() {
    fmt.Printf("%s会动!\n", a.name)
}

//Dog 狗
type Dog struct {
    Feet    int8
    *Animal //通过嵌套匿名结构体实现继承
}

func (d *Dog) wang() {
    fmt.Printf("%s会汪汪汪~\n", d.name)
}

func main() {
    d1 := &Dog{
        Feet: 4,
        Animal: &Animal{ //注意嵌套的是结构体指针
            name: "乐乐",
        },
    }
    d1.wang() //乐乐会汪汪汪~
    d1.move() //乐乐会动!
}

结构体字段的可见性

结构体中字段大写开头表示可公开访问小写表示私有(仅在定义当前结构体的包中可访问)。

参考链接:

http://www.topgoer.com/go%E5%9F%BA%E7%A1%80/%E7%BB%93%E6%9E%84%E4%BD%93.html

 

发布了410 篇原创文章 · 获赞 1345 · 访问量 207万+

Guess you like

Origin blog.csdn.net/fly910905/article/details/104360402