Golang 什么叫字面量和组合字面量?

Posted 知其黑、受其白

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Golang 什么叫字面量和组合字面量?相关的知识,希望对你有一定的参考价值。

阅读目录

阐述

>>> "name": "iswbm".get("name")  # 使用字面量
'iswbm'
>>>
>>> profile="name": "iswbm"   # 使用变量名
>>> profile.get("name")
'iswbm'

什么是字面量?

在 Go 中内置的基本类型有:

  • 布尔类型:bool

  • 11个内置的整数数字类型:int8, uint8, int16, uint16, int32, uint32, int64, uint64, int, uint和uintptr

  • 浮点数类型:float32和float64

  • 复数类型:complex64和complex128

  • 字符串类型:string

而这些基本类型值的文本,就是基本类型字面量。

比如下面这两个字符串,都是字符串字面量,没有用变量名或者常量名来指向这两个字面量,因此也称之为 未命名常量。

"hello, iswbm"

`hello,
iswbm`

同值不同字面量

值的字面量(literal)是代码中值的文字表示,一个值可能存在多种字面量表示。

举个例子,十进制的数值 15,可以由三种字面量表示。

// 16进制
0xF

// 8进制
0o17

// 2进制
0b1111

通过比较,可以看出他们是相等的

import "fmt"

func main() 
    fmt.Println(15 == 0xF)     // true
    fmt.Println(15 == 017)     // true
    fmt.Println(15 == 0b1111)  // true

字面量和变量有啥区别?

下面这是一段很正常的代码

func foo() string 
    return "hello"


func main() 
    bar := foo()
    fmt.Println(&bar)

可要是换成下面这样

func foo() string 
    return "hello"


func main() 
    fmt.Println(&foo())

上面这段代码就有问题了,运行后会报错

./demo.go:11:14: cannot take the address of foo()

你一定觉得很奇怪吧?

为什么先用变量名承接一下再取地址就不会报错,而直接使用在函数返回后的值上取地址就不行呢?

这是因为,如果不使用一个变量名承接一下,函数返回的是一个字符串的文本值,也就是字符串字面量,而这种基本类型的字面量是不可寻址的。

要想使用 & 进行寻址,就必须得用变量名承接一下。

什么是组合字面量?

所谓的组合字面量其实就是把对象的定义和初始化放在一起了。

接下来让我们看看结构体、数组、切片和map各自的常规方式和组合字面量方式。

结构体的定义和初始化

常规方式

常规方式这样定义是逐一字段赋值,这样就比较繁琐。

type Profile struct 
    Name string
    Age int
    Gender string


func main() 
    // 声明对象
    var xm Profile

    // 属性赋值
    xm.Name = "iswbm"
    xm.Age = 18
    xm.Gender = "male"

组合字面量方式

type Profile struct 
    Name string
    Age int
    Gender string


func main() 
    // 声明 + 属性赋值
    xm := Profile
        Name:   "iswbm",
        Age:    18,
        Gender: "male",
    

数组的定义和初始化

常规方式

在下面的代码中,我们在第1行定义了一个8个元素大小的字符串数组。然后一个一个的给元素赋值。即数组变量的定义和初始化是分开的。

var planets [8]string

planets[0] = "Mercury" //水星
planets[1] = "Venus" //金星
planets[2] = "Earth" //地球

组合字面量方式

该示例中,就是将变量 balls 的定义和初始化合并了在一起。

balls := [4]string"basketball", "football", "Volleyball", "Tennis"

slice的定义和初始化

常规方式

// 第一种
var s []string //定义切片变量s,s为默认零值nil
s = append(s, "hat", "shirt") //往s中增加元素,len(s):2,cap(s):2

// 第二种
s := make([]string, 0, 10) //定义s,s的默认值不为零值

组合字面量方式

由上面的常规方式可知,首先都是需要先定义切片,然后再往切片中添加元素。接下来我们看下组合字面量方式。

//定义和初始化一步完成,自动计算切片的容量和长度
s := []string"hat", "shirt" 

// or
var s = []string"hat", "shirt"

map的定义和初始化

常规方式

//通过make函数初始化
m := make(map[string]int, 10)
m["english"] = 99
m["math"] = 98

组合字面量方式

m := map[string]int 
    "english": 99,
    "math": 98,


//组合字面量初始化多维map
m2 := map[string]map[int]string 
    "english": 
        10: "english",
    ,

显然,使用组合字面量会比常规方式简单了不少。

字面量的寻址问题

字面量,说白了就是未命名的常量,跟常量一样,他是不可寻址的。

这边以数组字面量为例进行说明:

func foo() [3]int 
    return [3]int1, 2, 3


func main() 
    fmt.Println(&foo())
    // cannot take the address of foo()

以上是关于Golang 什么叫字面量和组合字面量?的主要内容,如果未能解决你的问题,请参考以下文章

03_数字的字面量

字面量和构造函数

JS基础_字面量和变量

Golang创建构造函数的方法详解

Java语言基础_类型和运算——字面量和常量

Golang学习之路:Go+体验分享及字面量讲解