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

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 为 ''.

本节这样,再会。

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏生信技能树

用 Excel 怎么了,你咬我啊?

伪题图:逼死强迫症之重新加载。下图为真题图 ? 2400字,约6分钟,思考问题的熊 专栏6 懒是人类进步的绊脚石,偷懒是人类进步的阶梯。如果你完成任何一项工作心...

40570
来自专栏calmound

图的着色

图着色问题,相邻的点颜色不同       基础知识:http://wenku.baidu.com/view/d7242fd1c1c708a1284a444d.h...

29170
来自专栏王肖的UT

GLSL-变量和类型

27440
来自专栏无所事事者爱嘲笑

常用的sort打乱数组方法真的有用?

28660
来自专栏二进制文集

LeetCode 004 Median of Two Sorted Arrays 详细分析

题目链接:https://leetcode.com/problems/median-of-two-sorted-arrays/

12110
来自专栏C/C++基础

金山WPS2016春季实习校园招聘笔试&面试问题回忆

下面将我在广州参加的2016年春季金山WPS实习招聘的整个过程中遇到的问题记录如下。不全,但是有些题目还是值得思考的。

13810
来自专栏数据结构与算法

1083 Cantor表

题目描述 Description 现代数学的著名证明之一是Georg Cantor证明了有理数是可枚举的。他是用下面这一张表来证明这一命题的: 1/1 1/2 ...

31670
来自专栏菜鸟前端工程师

JavaScript学习笔记005-运算符

9920
来自专栏用户2442861的专栏

对vector等STL标准容器进行排序操作

STL几乎封装了所有的数据结构中的算法,从链表到队列,从向量到堆栈,对hash到二叉树,从搜索到排序,从增加到删除......可以说,如果你理解了STL,你会...

34120
来自专栏章鱼的慢慢技术路

解密回文——栈

15430

扫码关注云+社区

领取腾讯云代金券