二、golang基础之常量

发布于:2024-07-04 ⋅ 阅读:(17) ⋅ 点赞:(0)

一、常量

(一)含义

常量是一个简单值的标识符,在程序运行时,不会被修改的量。
常量中的数据类型只可以是布尔型、数字型(整数型、浮点型和复数)和字符串型。
常量的定义格式:

const ind[type] = value;
你可以省略类型说明符 [type],因为编译器可以根据变量的值来推断其类型。

(二)定义

(1)显式类型定义:

const b string = "ABC";

(2)显式类型定义:

const b = "abc"

(3)例子

package main
import "fmt"

func main() {
	const length int = 10;
	const width int = 5;
	var area int;
	const a,b,c = 1,false,"str";
	
   area = LENGTH * WIDTH
   fmt.Printf("面积为 : %d\n", area)
   println(a, b, c)  
}

(三)内置函数

常量可以用len(), cap(), unsafe.Sizeof()常量计算表达式的值。常量表达式中,函数必须是内置函数,否则编译不过:

package main
import "unsafe"

const (
	a = "abc";
	b = len(a);
	c = unsafe.Sizeof(a);
)
func main(){
    println(a, b, c)
}
输出结果为:abc, 3, 16


字符串类型在 go 里是个结构, 包含指向底层数组的指针和长度,这两部分每部分都是 8 个字节,所以字符串类型大小为 16 个字节。

二、优雅的常量 iota

有些概念有名字,并且有时候我们关注这些名字,甚至(特别)是在我们代码中。

const (
    CCVisa            = "Visa"
    CCMasterCard      = "MasterCard"
    CCAmericanExpress = "American Express"
)

在其他时候,我们仅仅关注能把一个东西与其他的做区分。有些时候,有些时候一件事没有本质上的意义。比如,我们在一个数据库表中存储产品,我们可能不想以 string 存储他们的分类。我们不关注这个分类是怎样命名的,此外,该名字在市场上一直在变化。

我们仅仅关注它们是怎么彼此区分的。

const (
    CategoryBooks    = 0
    CategoryHealth   = 1
    CategoryClothing = 2
)

使用 0, 1, 和 2 代替,我们也可以选择 17, 43, 和 61。这些值是任意的。

在 Go,常量有许多微妙之处。当用好了,可以使得代码非常优雅且易维护的。

(一)自增长

在 golang 中,一个方便的习惯就是使用iota标示符,它简化了常量用于增长数字的定义,给以上相同的值以准确的分类。

const (
    CategoryBooks = iota // 0
    CategoryHealth       // 1
    CategoryClothing     // 2
)

(二)iota和表达式

iota可以做更多事情,而不仅仅是 increment。更精确地说,iota总是用于 increment,但是它可以用于表达式,在常量中的存储结果值。

type Allergen int


const (
    IgEggs Allergen = 1 << iota         // 1 << 0 which is 00000001
    IgChocolate                         // 1 << 1 which is 00000010
    IgNuts                              // 1 << 2 which is 00000100
    IgStrawberries                      // 1 << 3 which is 00001000
    IgShellfish                         // 1 << 4 which is 00010000
)

这个工作是因为当你在一个const组中仅仅有一个标示符在一行的时候,它将使用增长的iota取得前面的表达式并且再运用它,
在 Go 语言的spec中, 这就是所谓的隐性重复最后一个非空的表达式列表.

如果你对鸡蛋,巧克力和海鲜过敏,把这些 bits 翻转到 “on” 的位置(从左到右映射 bits)。然后你将得到一个 bit 值00010011,它对应十进制的 19。

fmt.Println(IgEggs | IgChocolate | IgShellfish)


// output:
// 19
type ByteSize float64


const (
    _           = iota                   // ignore first value by assigning to blank identifier
    KB ByteSize = 1 << (10 * iota)       // 1 << (10*1)
    MB                                   // 1 << (10*2)
    GB                                   // 1 << (10*3)
    TB                                   // 1 << (10*4)
    PB                                   // 1 << (10*5)
    EB                                   // 1 << (10*6)
    ZB                                   // 1 << (10*7)
    YB                                   // 1 << (10*8)
)
const (
    Apple, Banana = iota + 1, iota + 2
    Cherimoya, Durian
    Elderberry, Fig
)

在下一行增长,而不是立即取得它的引用。

// Apple: 1
// Banana: 2
// Cherimoya: 2
// Durian: 3
// Elderberry: 3
// Fig: 4