『Go 语言学习专栏』-- 第十二期

作者: 谢小路 | 来源:发表于2018-06-03 12:43 被阅读7次
    go-12.png 12-1.png

    大家好,我叫谢伟,是一名程序员。

    如何你想要寻找一份和编程相关的职位,经验不太够的话,面试官会考察你什么?

    • 基础,比如你对某编程语言的理解程度
    • 学习能力,即如何展现你的学习能力

    本节的主题,Go 语言中的:值语义和引用语义

    问题列表:

    • 值语义和引用语义的区别是什么?
    • 内置的类型哪些是值语义,哪些是引用语义?
    • make 和 new 有什么区别?

    值语义和引用语义

    Go 语言中的大多数类型都是值语义。值语义和引用的区别在于赋值之后,重新赋值,是否会改变原值。

    如果不改变原值,则是值语义。否则是引用语义,引用语义比值语义拥有更复杂的存储结构。比如分配内存、指针、长度、容量等。

    package main
    
    import "fmt"
    
    func main() {
    
        // map、slice、channel
    
        var number int
    
        number = 0
        copyNumber := number
        copyNumber = 3
    
        fmt.Printf("----: new=%v, old=%v\n", copyNumber, number)
    
        var List = [2]int{1, 2}
    
        copyList := List
        copyList[1] = 4
    
        fmt.Printf("----: new=%v, old=%v\n", copyList, List)
    
        type Info struct {
            Name   string
            Age    int
            School string
        }
    
        oldInfo := Info{
            "xieWei", 20, "shanghaiUniversity",
        }
    
        newInfo := oldInfo
        newInfo.Name = "xieWei2"
    
        fmt.Printf("----: new=%v, old=%v\n", newInfo, oldInfo)
    
        var Body = make(map[string]string)
        Body["name"] = "xieWei"
        Body["School"] = "shanghaiUniversity"
    
        newBody := Body
        newBody["name"] = "xieWei2"
        newBody["Age"] = "20"
    
        fmt.Printf("----: new=%v, old=%v\n", newBody, Body)
    
        var oldSlice = []int{1, 2, 3, 4}
    
        newSlice := oldSlice
        newSlice[3] = 10
        newSlice = append(newSlice, 100)
    
        fmt.Printf("----: new=%v, old=%v\n", newSlice, oldSlice)
    
    }
    
    

    结果:

    ----: new=3, old=0
    ----: new=[1 4], old=[1 2]
    ----: new={xieWei2 20 shanghaiUniversity}, old={xieWei 20 shanghaiUniversity}
    ----: new=map[name:xieWei2 School:shanghaiUniversity Age:20], old=map[name:xieWei2 School:shanghaiUniversity Age:20]
    ----: new=[1 2 3 10 100], old=[1 2 3 10]
    

    结论:

    • 在 Go 语言中值语义和引用语义的区别发生在赋值语句中。map、slice、channel 这三种类型

    • 赋值之后,修改新的对象,会改变原对象的内容,是因为引用语义底层都指向的是地址

    • 引用类型必须使用 make 函数创建,完成内存分配和相关属性的初始化。即:对应的值上都有初始化值,比如 int 类型,则初始化值为0, 比如 string 类型,则初始化为空,诸如此类

    package main
    
    func main(){
        var exampleSlice = make([]int, 4)
        exampleSlice[0] = 1
        fmt.Println(exampleSlice)
    }
    
    

    结果:

    [1 0 0 0]
    

    只赋值第一个元素,其他元素默为0。

    值语义的数据,想要改变元素值,需要使用指针:

        var exampleInt int
    
        exampleInt = 4
    
        newExampleInt := &exampleInt
        *newExampleInt = 40
    
        fmt.Println(exampleInt, *newExampleInt)
    

    结果:

    40 40
    

    内置函数 new 按指定类型分配零值内存, 返回的是一个指针。

        type Info struct {
            Name   string
            Age    int
            School string
        }
    
        exampleBigInfo := new(Info)
        fmt.Println(exampleBigInfo)
    

    结果:

    &{ 0 }
    

    可以看出:

    • 返回指针
    • 存在零值,比如 Name 为 '', Age 为0,School 为 ''.

    本节这样,再会。

    相关文章

      网友评论

        本文标题:『Go 语言学习专栏』-- 第十二期

        本文链接:https://www.haomeiwen.com/subject/eeorsftx.html