当前位置: 首页 > 科技观察

Go:什么是字面量和复合字面量?

时间:2023-03-13 12:48:50 科技观察

#0.前言不怕大家笑话。去年年初刚开始学习围棋基础的时候,有一句话困扰了我很久。这个词是字面意思。之所以让我难以理解,是因为在Go之前,我写过Python,而且写了很多年。在Python中,一切都是对象,不管是字面量值)没有变量名可以接管,也没有使用上的区别,所以在学习Go之前,其实并不知道字面量的概念。>>>{"name":"iswbm"}.get("name")#使用文字'iswbm'>>>>>profile={"name":"iswbm"}#使用变量名>>>profile.get("name")'iswbm'那么究竟什么是文字呢?为什么在那么多基础教程中反复提到,却好像没有人解释这个名词的概念?是因为这是常识吗??尴尬的。.相信正在阅读本文的你也可能有这样的疑问。今天我就来梳理一下我理解中的字面量是什么意思?它和普通变量有什么区别?#1.什么是字面量?Go内置的基本类型有:布尔类型:bool11内置整数数值类型:int8,uint8,int16,uint16,int32,uint32,int64,uint64,int,uint,uintptr浮点型:float32和float64复杂类型:complex64和complex128字符串类型:string而这些基本类型值的文本就是基本类型字面量。比如下面两个字符串都是字符串字面量,没有用变量名或者常量名来指向这两个字面量,所以也叫无名常量。"hello,iswbm"`hello,iswbm`#2.同值字面量和不同字面量值的字面量是代码中值的字面量表示,一个值可能有多个字面量表示。比如十进制值15可以用三种字面量值来表示//16base0xF//8base0o17//2base0b1111通过比较可以看出它们是相等的import"fmt"funcmain(){fmt.Println(15==0xF)//truefmt.Println(15==017)//truefmt.Println(15==0b1111)//true}#3、字面量和变量有什??么区别?下面是很正常的代码funcfoo()string{return"hello"}funcmain(){bar:=foo()fmt.Println(&bar)}但是如果换成下面的funcfoo()string{return"hello"}funcmain(){fmt.Println(&foo())}但其实这段代码是有问题的,运行后会报错。/demo.go:11:14:cannottaketheaddressoffoo()一定要找到奇怪的?为什么先用如果继承了变量名再取地址,不会报错,但是直接用函数返回的值取地址不就可以了吗?这是因为,如果不使用变量名来接管,函数返回的是一串文本值,即字符串字面量,这种基本类型的字面量是不可寻址的。如果要用&来寻址,就必须用变量名来接管。#4.什么是复合文字?首先看Go文档中复合字面量(CompositeLiteral)的定义:复合字面量为结构体、数组、切片和映射构造值,并在每次求值时创建一个新值。它们由文字类型和后跟大括号绑定的元素列表组成。每个元素前面可以有一个相应的键。翻译成中文大致如下:组合字面量就是为结构体、数组、切片和映射构造值,每次都创建新的值。它们由文字类型后跟花括号和元素列表组成。每个元素前面都可以有一个关联的键。你是什??么意思?所谓组合字面量,其实就是把对象的定义和初始化放在一起。接下来让我们看看结构、数组、切片和映射的常规和复合文字。结构定义和初始化让我们看看结构的一般定义和初始化是什么样的。常规方法常规方法是一个一个赋值,比较繁琐。typeProfilestruct{NamestringAgeintGenderstring}funcmain(){//声明对象varxmProfile//属性赋值xm.Name="iswbm"xm.Age=18xm.Gender="male"}组合字面量方法typeProfilestruct{NamestringAgeintGenderstring}funcmain(){//声明+属性赋值xm:=Profile{Name:"iswbm",Age:18,Gender:"male",}}数组的定义和初始化常规方法在下面的代码中,我们在第一行定义了一个8的Element-sized字符串数组。然后对元素一一赋值。即数组变量的定义和初始化是分开的。varplanets[8]stringplanets[0]="Mercury"//Mercuryplanets[1]="Venus"//Venusplanets[2]="Earth"//地球组合字面量法本例中变量balls的定义和初始化合并在一起。balls:=[4]string{"basketball","football","Volleyball","Tennis"}slice定义和初始化的一般方式//第一种vars[]string//定义slice变量s,s是默认的零值nils=append(s,"hat","shirt")//给s添加元素,len(s):2,cap(s):2//第二种s:=make([]string,0,10)//定义s,s的默认值不为0。结合字面量方法从上面的常规方法我们可以看出,首先需要先定义切片,然后向切片中添加元素。接下来,我们看看组合字面量的方式。s:=[]string{"hat","shirt"}//一步完成定义和初始化,自动计算切片的容量和长度//或vars=[]string{"hat","shirt"}map的定义和定义Normalwayofinitialization//通过make函数初始化m:=make(map[string]int,10)m["english"]=99m["math"]=98combinedliteralmethodm:=map[string]int{"english":99,"math":98,}//多维组合文字初始化mapm2:=map[string]map[int]string{"english":{10:"english",},}显然,使用Combiningliterals比通常的方式要简单得多。#5.字面量寻址问题字面量,说白了,就是无名常量。与常量一样,它们不可寻址。这里我们以数组字面量为例进行说明关于addressability可以在我上一篇文章(Go面试题008:如何理解Go中的addressable和non-addressable?)里面总结的很详细。是不是很简单?跟随明哥征服围棋各个角落的知识。来吧,让我们在下一篇文章中看到。转载本文请联系围棋编程时间公众号。