Go语言中的常量和变量的定义

常量(Constants)和iota

常量包含不会发生更改的数据。常量的数据类型只能是boolean、number(int/float/complex)或string。

定义方式:

const NAME [TYPE] = VALUE

TYPE基本可以省略,因为常量都是简单数据类型,编译器可以根据值推断出它的数据类型。

例如:

const Pi = 3.14159

常量在编译期间被评估,因此定义的常量必须是在编译期间就能计算出来的结果。例如调用一些运行期间的函数来生成常量的值就是错误的,因为在编译期间无法调用这些运行期间的函数。常量的值定义好后,无法在运行期间更改,否则会报错。

const c = 3+2 // 正确 const d = getNumber() // 错误

常量的精度可以随意长,Go不会出现精度溢出的问题。且常量赋值时,如果值太长,可以使用续行符\:

const Ln2= 0.693147180559945309417232121458\ 176568075500134360255254120680009 const Log2E= 1/Ln2 const Billion = 1e9

Go中只有将超出变量精度的值赋值给变量时才会出现溢出问题。

可以一次性定义多个常量:

const beef, two, c = "meat", 2, "veg" const Monday, Tuesday, Wednesday = 1, 2, 3 const (    Monday, Tuesday, Wednesday = 1, 2, 3 Thursday, Friday, Saturday = 4, 5, 6 )

常量可以用枚举。定义了下面的常量后,Female就代表了数值1。

const (    Unknown = 0 Female = 1 Male = 2 )

可以使用iota实现枚举,iota自身是builtin包中定义的一个常量,其值为0,它用于在常量中定义序列数,从0开始增加:

const (    a = iota b = iota c = iota )

当iota第一次调用时,产生数值0,在新行中再次调用iota,将自动增加1,所以上面的a=0,b=1,c=2。上面的常量枚举可以简写成等价形式:

const (    a = iota b    c)

iota不能用于运行期间,因为它是小写字母开头的常量,不会被导出。下面的代码会报错:iota未定义

var a int = iota

iota也可以用于表达式中,例如iota+50表示将当前的iota值加上50。

每个常量块(const block)结构都会重置和初始化iota的值为0

func main() { const a = iota // a=0 const b = iota + 3 // b=3 const c,d = iota,iota+3 // c=0,d=3 const (        e = iota // e=0 f = iota + 4 // f=5 g // g=6 ) println(a,b,c,d,e,f,g)}

变量

在使用变量之前,有两个过程:声明变量、变量赋值。声明变量也常被称为"定义变量"。变量声明后必须使用,否则会报错。

定义变量的常用方式:

var identifier type

例如:

var a int var b bool var str string // 或者 var (    a int b bool str string )

当变量声明的时候,会做默认的赋0初始化,每种数据类型的默认赋0初始化的0值不同。例如int类型的0值为数值0,float的0值为0.0,string类型的0值为空"",bool类型的0值为false,数据结构的0值为nil,struct的0值为字段全部赋0。

变量在编译期间就可以获取到它的值,但如果赋值给变量的值需要经过运行期间的计算,则需要延迟到运行期间才能获取对应的值。

var a int = 15 // 编译期间赋值好 var b int = 15/3 // 编译期间赋值好 var c = getNumber() // 运行期间才赋值

声明和赋值可以结合:

var a int = 15 var i = 5 var b bool = false var str string = "Hello World"

声明和赋值结合的时候,对于简单数据类型的值,可以省略type部分,因为Go可以根据值自己推断出类型:

var a = 15 var b = false var str = "Hello World" var (    a = 15 b = false str = "Hello World" numShips = 50 city string )

因为要推断数据类型,所以类型推断操作是在运行期间完成的。

在使用推断类型的赋值时,如果想要指定特定类型,需要显式指定。例如整数数值推断的类型为int,要想让它保存到int64中,则必须显式指定类型:

var a int64 = 2

要推断类型必须是声明和赋值一起的,否则没有值,无法根据值去推断。例如var a是错的。

除了上面的推断方式,通过:=符号也能实现声明和赋值结合,它也会根据数据类型进行推断,连var关键字都省略了:

a := 50

但是:=只能在函数代码块内部使用,在全局作用域下使用将报错,因为类型推断是在运行期执行的,而全局范围内的变量声明部分是在编译期间就决定好的。例如,下面的将报错:

12a := 10 func main() { println(a) }

变量声明之后不能再次声明(除非在不同的作用域),之后只能使用=进行赋值。例如,执行下面的代码将报错:

package main import ("fmt") func main(){ x:=10 fmt.Println("x =",x)    x:=11 fmt.Println("x =",x)}

错误如下:

12# command-line-arguments .\test.go:8:3: no new variables on left side of :=

报错信息很明显,:=左边没有新变量。

如果仔细看上面的报错信息,会发现no new variables是一个复数。实际上,Go允许我们使用:=一次性声明、赋值多个变量,而且只要左边有任何一个新变量,语法就是正确的。

func main(){    name,age := "longshuai",23 fmt.Println("name:",name,"age:",age) // name重新赋值,因为有一个新变量weight weight,name := 90,"malongshuai" fmt.Println("name:",name,"weight:",weight)}

需要注意,name第二次被:=赋值,Go第一次推断出该变量的数据类型之后,就不允许:=再改变它的数据类型,因为只有第一次:=对name进行声明,之后所有的:=对name都只是简单的赋值操作。

例如,下面将报错:

weight,name := 90,80

错误信息:

.\test.go:11:14: cannot use 80 (type int) as type string in assignment

另外,变量声明之后必须使用,否则会报错,因为Go对规范的要求非常严格。例如,下面定义了weight但却没使用:

12weight,name := 90,"malongshuai" fmt.Println("name:",name)

错误信息:

.\test.go:11:2: weight declared and not used

变量作用域(scope)

Go语言的作用域采用的是词法作用域,意味着文本段定义所在位置决定了可看见的值范围。

  • 定义在函数内部的变量为局部变量,只在函数内部可见定义在代码块内(如{…CODE…})的变量也是局部变量,除了代码块就消失定义在代码块外、函数外的变量为包变量或者全局变量,它们可以被同一个目录下同一个包的多个文件访问(因为Go中一个目录下只能定义一个包,但一个包可以分成多个文件)如果变量的名称以小写字母开头,则其它包不能访问该变量如果变量的名称以大写字母开头,则其它包可以访问该变量

  • 不同scope的变量名可以冲突,但建议采取名称唯一的方式为变量命名。

原创文章,作者:YXFZR,如若转载,请注明出处:https://www.beidanyezhu.com/a/28840.html

(0)
YXFZR的头像YXFZR
上一篇 2025-01-27
下一篇 2025-02-01

相关推荐

  • 无形资产的概念(无形资产定义)

    无形资产的概念和特征无形资产是指企业拥有或控制的没有实物形态的可辨认非货币性资产。无形资产具有三个主要特征: 一是不具有实物形态。无形资产是不具有实物形态的非货币性资产。 二是具有…

  • 2022(妇女的定义)

    熊丰 河南文艺出版社 妇女节 快乐 今天是3月8日国际妇女节, 你打算发朋友圈吗? 要怎么发呢—— “女神节快乐”? “女王节快乐”? 又或者, “女生节”?“仙女节”? 1. 婚…

  • Go语言中的自定义类型怎么定义

    1. 什么是自定义类型 在 Go 语言中,自定义类型指的是使用 type 关键字定义的新类型,它可以是基本类型的别名,也可以是结构体、函数等组合而成的新类型。自定义类型可以帮助我们…

  • 怎么使用Go语言sync包与锁实现限制线程对变量的访问

    Go语言中 sync 包里提供了互斥锁 Mutex 和读写锁 RWMutex 用于处理并发过程中可能出现同时两个或多个协程(或线程)读或写同一个变量的情况。 为什么需要锁 锁是 s…

  • go语言如何定义数组

    go语言定义数组的方法有三种,分别是:1、传统方式定义数组,如“var arr [8]int=[8]int”;2、自动类型推导,如“arr:=[10]int”;3、三个点自动类型推…

  • Go语言接口类型怎么定义

    接口 接口是用来定义行为的类型,定义的行为不由接口直接实现,而由通过方法由定义的类型实现 Golang中,接口是一组方法的签名,是语言中一个重要的组成部分,其目的是通过引入一个中间…

  • Go语言变量与常量如何声明与使用

    变量 什么是变量?变量是一块可以随时存放数据的内存区域。在我们申请这块内存区域(声明变量)时,需要指定变量名以及变量的数据类型,数据类型用于说明变量可以存放什么值。 Go是强类型语…

  • Go语言的变量与常量怎么定义

    1.变量交换 简单阐述一下什么是变量交换,顾名思义,就是将变量的值进行交换的一个动作 例如我们定义了两个变量a:=10和b:=20,那么这时候我们想要将两个变量的值进行交换的话,在…

  • go语言变量的作用域是什么

    go语言变量有2种作用域:1、局部变量,是在函数级别和块级别内声明的变量;局部变量只能在它们的块或函数中访问,已经声明的局部变量不能在同一块或函数中重新声明。2、全局变量,是在包级…

    2025-02-20
  • go语言中结构体方法如何定义

    go语言中结构体方法的定义方法:1、定义一个结构体,语法“type point struct {….}”;2、将结构体作为接收者来定义结构体方法,语法“func (接收…

分享本页
返回顶部