【无标题】

本文详细介绍了Go语言中的变量声明、初始化、赋值以及局部和全局变量的概念,包括变量的声明方式如类型推导和简略声明。接着讨论了常量的定义,包括字面常量、预定义常量和枚举的使用。最后概述了Go的算术、关系、逻辑、位和赋值运算符,通过示例展示了各种运算符的用法。
摘要由CSDN通过智能技术生成

目录

1、变量

2、常量

3、运算符

算术运算符:

关系运算符:

逻辑运算符:

位运算符:

赋值运算符:

其他运算符:


1、变量

变量是几乎所有编程语言中最基本的组成元素。从根本上说,变量相当于是对一块数据存储空间的命名,程序可以通过定义一个变量来申请一块数据存储空间,之后可以通过引用变量名来
使用这块存储空间。

Go语言中的变量使用方式与C语言接近,但具备更大的灵活性。
 

声明变量的一般形式是使用 var 关键字:
var identifier(变量) type(数据类型)
 

变量声明有如下三种:
第一种 全定义,指定变量类型,声明后若不赋值,使用默认值。
var v_name v_type
比如:var a int = 10 //内存申请一个a变量,指定内存大小为int尺寸,内容为空。
第二种 类型推导,根据值自行判定变量类型。
var v_name = value
比如:var b = 10 //内存申请一个a变量,并向该变量中存储10这个数字。内存尺寸自动推导
第三种 简略声明,省略var, 注意 :=左侧的变量不应该是已经声明过的,否则会导致
编译错误。
使用操作符 := 可以高效地创建一个新的变量,称之为初始化声明。
:= 不能被用在函数体外,也就是说,当你打算声明一个全局变量时,你只能使用var。
v_name := value
比如:c := 10


 

Go变声明时候会给初始值(默认值)

  1. 数字类型 int float byte rune 为 0
  2. string 为空字符串,注意c语言中没有这个类型
  3. complex 为 (0+0i)
  4. bool类型为false
  5. error类型为
     

变量声明语句不需要使用分号作为结束符。与C语言相比,Go语言摒弃了语句必须以
分号作为语句结束标记的习惯。


var关键字的另一种用法是可以将若干个需要声明的变量放置在一起,免得程序员需
要重复
写var关键字,如下所示:
 

var (                                                               
v1 int
v2 string
)


//类型相同多个变量, 非全局变量

var vname1, vname2, vname3 type
vname1, vname2, vname3 = v1, v2, v3
var vname1, vname2, vname3 = v1, v2, v3 //和python很像,不需要显示声明类型,自动推断
vname1, vname2, vname3 := v1, v2, v3 //出现在:=左侧的变量不应该被声明过的,否则导致编译错误
							           //类型不同多个变量, 全局变量, 局部变量不能使用这种方式


变量初始化:
对于声明变量时需要进行初始化的场景,var关键字可以保留,但不再是必要的元
素,如下所示:
var v1 int = 10 // 正确的使用方式1
var v2 = 10 // 正确的使用方式2,编译器可以自动推导出v2的类型
v3 := 10 // 正确的使用方式3,编译器可以自动推导出v3的类型
以上三种用法的效果是完全一样的。与第一种用法相比,第三种用法需要输入的字符数大大减少,是懒程序员和聪明程序员的最佳选择。这里Go语言也引入了另一个C和C++中没有的符号(冒号和等号的组合:=),用于明确表达同时进行变量声明和初始化的工作。
 

指定类型已不再是必需的,Go编译器可以从初始化表达式的右值推导出该变量应该声
明为哪种类型,这让Go语言看起来有点像动态类型语言,尽管Go语言实际上是不折不扣的强类型语言。
当然,出现在:=左侧的变量不应该是已经被声明过的,否则会导致编译错误,比如下
面这个写法:
var i int
i := 2
会导致类似如下的编译错误:
no new variables on left side of :=
 

变量赋值:
在Go语法中,变量初始化和变量赋值是两个不同的概念。下面为声明一个变量之后的
赋值过程:
var v10 int //声明
v10 = 123 //赋值使用 没有引用

Go语言的变量赋值与多数语言一致,但Go语言中提供了C/C程序员期盼多年的多
重赋值功能,
比如下面这个交换i和j变量的语句:
i, j = j, i

优点为减少内存

(语法支持)
在不支持多重赋值的语言中,交互两个变量的内容需要引入一个中间变量:
t = i;

i = j;

j = t;

(函数调用)


多重赋值的特性在Go语言库的实现中也被使用得相当充分,在介绍函数的多重返回值时,将对其进行更加深入的介绍。总而言之,多重赋值功能让Go语言与C/C++语言相比可以非常明显地减少代码行数。
 

匿名变量:
我们在使用传统的强类型语言编程时,经常会出现这种情况,即在调用函数时为了获
取一个值,却因为该函数返回多个值而不得不定义一堆没用的变量。在Go中这种情况可以通过结合使用多重返回和匿名变量
来避免这种丑陋的写法,让代码看起来更加优雅。
假设GetName()函数的定义如下,它返回3个值,分别为firstName、lastName和
nickName:

func GetName() (firstName, lastName, nickName string) {
return "May", "Chan", "Chibi Maruko"}

如:



若只想获得nickName,则函数调用语句可以用如下方式编写:
_,_ , nickName := GetName()


这种用法可以让代码非常清晰,基本上屏蔽掉了可能混淆代码阅读者视线的内容,从而大幅降低沟通的复杂度和代码维护的难度。
 

局部变量
在函数体内声明的变量称之为局部变量,它们的作用域只在函数体内,参数和返回值变量也是局部变量。
以下实例中 main() 函数使用了局部变量 a, b, c:

package main
import "fmt"
func main() {
/ 声明局部变量 /
	var a, b, c int
/ 初始化参数 /
	a = 10
	b = 20
	c = a + b
fmt.Printf ("结果: a = %d, b = %d and c = %d\n", a, b, c)
}


以上实例执行输出结果为:
结果: a = 10, b = 20 and c = 30
 

全局变量
在函数体外声明的变量称之为全局变量,全局变量可以在整个包甚至外部包(被导出
后)使用。
全局变量可以在任何函数中使用,以下实例演示了如何使用全局变量:

package main
import "fmt"
/ 声明全局变量 /
var g int
func main() {
/ 声明局部变量 /
	var a, b int
/ 初始化参数 /
	a = 10
	b = 20
	g = a + b
fmt.Printf("结果: a = %d, b = %d and g = %d\n", a, b, g)
}


以上实例执行输出结果为:
结果: a = 10, b = 20 and g = 30
Go 语言程序中全局变量与局部变量名称可以相同,但是函数内的局部变量会被优先考虑。实例如下:

package main
import "fmt"
/ 声明全局变量 /
var g int = 20
func main() {
/ 声明局部变量 /
var g int = 10
fmt.Printf ("结果: g = %d\n", g)
}


以上实例执行输出结果为:
结果: g = 10
 

2、常量

在Go语言中,常量是指编译期间就已知且不可改变的值。

常量可以是数值类型(包括整型、浮点型和复数类型)、布尔类型、字符串类型等

字面常量

所谓字面常量(literal),是指程序中硬编码的常量,如:-12

3.14159265358979323846 // 浮点类型的常量

3.2+12i // 复数类型的常量

true // 布尔类型的常量

"foo" // 字符串常量

在其他语言中,常量通常有特定的类型,比如-12在C语言中会认为是一个int类型的常量。

如果要指定一个值为-12的long类型常量,需要写成-12l,这有点违反人们的直观感觉。

Go语言的字面常量更接近我们自然语言中的常量概念,它是无类型的。只要这个常量在相应类型的值域范内,就可以作为该类型的常量,比如上面的常量-12,它可以赋值给int、uint、

int32、int64、float32、float64、complex64、complex128等类型的变量。

常量定义

通过const关键字,你可以给字面常量指定一个友好的名字:

const Pi float64 = 3.14159265358979323846

const zero = 0.0 // 无类型浮点常量

const (

size int64 = 1024

eof = -1      // 无类型整型常量

)

const u, v float32 = 0, 3 // u = 0.0, v = 3.0,常量的多重赋值

const a, b, c = 3, 4, "foo"  // a = 3, b = 4, c = "foo", 无类型整型和字符串常量

Go的常量定义可以限定常量类型,但不是必需的。如果定义常量时没有指定类型,那么它与字面常量一样,

是无类型常量。常量定义的右值也可以是一个在编译期运算的常量表达式,比如

const mask = 1 << 3

由于常量的赋值是一个编译期行为,所以右值不能出现任何需要运行期才能得出结果的表达式,

比如试图以如下方式定义常量就会导致编译错误:

const Home = os.Getenv("HOME") // os.Getenv("HOME")动态获取当前用户的家目录

原因很简单,os.GetEnv()只有在运行期才能知道返回结果,

在编译期并不能确定,所以无法作为常量定义的右值.

预定义常量:

Go语言预定义了这些常量:true、false和iota。

iota比较特殊,可以被认为是一个可被编译器修改的常量,在每一个const关键字出现时被重置为0,

然后在下一个const出现之前,每出现一次iota,其所代表的数字会自动增1。

从以下的例子可以基本理解iota的用法.

package main 
import "fmt" 
func main() { 
const ( 
 a = iota //0 (iota在每个const开头被重设为0) 
 b //1 
 c //2 
 d = "ha" //独立值,iota += 1 
 e //"ha" iota += 1 
 f = 100 //iota +=1 
 g //100 iota +=1 
 h = iota //7,恢复计数 
 i    //8 
) 
fmt.Println(a,b,c,d,e,f,g,h,i) 
} 

以上实例运行结果为:

0 1 2 ha ha 100 100 7 8

枚举

枚举指一系列相关的常量,比如下面关于一个星期中每天的定义。通过上一节的例子,我们看到可以用

在const后跟一对圆括号的方式定义一组常量,这种定义法在Go语言中通常用于定义

枚举值。

Go语言并不支持众多其他语言明确支持的enum关键字。下面是一个常规的枚举表示法,

其中定义了一系列整型常量.

const ( 
 Sunday = iota 
 Monday 
 Tuesday 
 Wednesday 
 Thursday 
 Friday 
 Saturday 
 numberOfDays // 这个常量没有导出 
) 

同Go语言的其他符号(symbol)一样,以大写字母开头的常量在包外可见。 小写字母包外不可见

以上例子中numberOfDays为包内私有,其他符号则可被其他包访问。

枚举应用案例:

package main

import "fmt"

const (

Running int = iota

Pending

Stopped

)

func main() {

fmt.Println("State running: ", Running)

fmt.Println("State pending: ", Pending)

fmt.Println("State Stoped: ", Stopped)

}

说明iota可以初始化counst的初始值防止常量内存大小未知,会有如下编译错误哦。

没有导出的const常量不能外部使用

3、运算符

Go 语言内置的运算符有:

• 算术运算符

• 关系运算符

• 逻辑运算符

• 位运算符

• 赋值运算符

• 其他运算符

算术运算符:

测试代码:

package main 
import "fmt" 
func main() { 
 var a int = 21 
 var b int = 10 
 var c int 
 c = a + b 
 fmt.Printf("第一行 - c 的值为 %d\n", c ) 
 c = a - b 
 fmt.Printf("第二行 - c 的值为 %d\n", c ) 
 c = a * b 
 fmt.Printf("第三行 - c 的值为 %d\n", c ) 
 c = a / b 
 fmt.Printf("第四行 - c 的值为 %d\n", c ) 
 c = a % b 
 fmt.Printf("第五行 - c 的值为 %d\n", c ) 
 a++ 
 fmt.Printf("第六行 - c 的值为 %d\n", a ) 
 a-- 
 fmt.Printf("第七行 - c 的值为 %d\n", a ) 
} 

以上实例运行结果:

第一行 - c 的值为 31

第二行 - c 的值为 11

第三行 - c 的值为 210

第四行 - c 的值为 2

第五行 - c 的值为 1

第六行 - c 的值为 22

第七行 - c 的值为 21

注意: go有i++,但没有++i,写++i会报错!--运算符同理。

i++ i---的功能单独语句使用,不允许在表达式中使用。 a=i++ 编译异常。

关系运算符:

测试用例:

package main 
import "fmt" 
func main() { 
 var a int = 21 
 var b int = 10 
 if a == b { 
 fmt.Printf("第一行 - a 等于 b\n" ) 
 } else { 
 fmt.Printf("第一行 - a 不等于 b\n" ) 
 } 
    
 if a < b { 
 fmt.Printf("第二行 - a 小于 b\n" ) 
 } else { 
 fmt.Printf("第二行 - a 不小于 b\n" ) 
 } 
    
 if a > b { 
 fmt.Printf("第三行 - a 大于 b\n" ) 
 } else { 
 fmt.Printf("第三行 - a 不大于 b\n" ) 
 } 
    
 /* Lets change value of a and b */ 
 a = 5 
 b = 20 
 if a <= b { 
 fmt.Printf("第四行 - a 小于等于 b\n" ) 
 } 
 if b >= a { 
 fmt.Printf("第五行 - b 大于等于 a\n" ) 
 } 
} 

以上实例运行结果:

第一行 - a 不等于 b

第二行 - a 不小于 b

第三行 - a 大于 b

第四行 - a 小于等于 b

第五行 - b 大于等于 a

逻辑运算符:

测试用例:

package main 
import "fmt" 
func main() { 
 var a bool = true 
 var b bool = false 
 if a && b { 
 fmt.Printf("第一行 - 条件为 true\n" ) 
 } 
 if a || b { 
 fmt.Printf("第二行 - 条件为 true\n" ) 
 } 
 /* 修改 a 和 b 的值 */ 
 a = false 
 b = true 
 if a && b { 
 fmt.Printf("第三行 - 条件为 true\n" ) 
 } else { 
 fmt.Printf("第三行 - 条件为 false\n" ) 
 } 
 if !(a && b) { 
 fmt.Printf("第四行 - 条件为 true\n" ) 
 } 
} 

以上实例运行结果:

第二行 - 条件为 true

第三行 - 条件为 false

第四行 - 条件为 true

位运算符:

左移几个会向左边扔掉几个,右移几个会向右边扔掉几个

左移几位就是乘2的n次幂,右移几位就是除以2的n次幂

测试用例:

package main 
import "fmt" 
func main() { 
 var a uint = 60 /* 60 = 0011 1100 */ 
 var b uint = 13 /* 13 = 0000 1101 */ 
 var c uint = 0 
 c = a & b /* 12 = 0000 1100 */ 
 fmt.Printf("第一行 - c 的值为 %d\n", c ) 
 c = a | b /* 61 = 0011 1101 */ 
 fmt.Printf("第二行 - c 的值为 %d\n", c ) 
 c = a ^ b /* 49 = 0011 0001 */ 
 fmt.Printf("第三行 - c 的值为 %d\n", c ) 
 c = a << 2 /* 240 = 1111 0000 */ 
 fmt.Printf("第四行 - c 的值为 %d\n", c ) 
c = a >> 2 /* 15 = 0000 1111 */ 
 fmt.Printf("第五行 - c 的值为 %d\n", c ) 
} 

以上实例运行结果:

第一行 - c 的值为 12

第二行 - c 的值为 61

第三行 - c 的值为 49

第四行 - c 的值为 240

第五行 - c 的值为 15

赋值运算符:

注意:=和==

测试用例:

package main 
import "fmt" 
func main() { 
 var a int = 21 
 var c int 
 c = a 
 fmt.Printf("第 1 行 - = 运算符实例,c 值为 = %d\n", c ) 
 c += a 
 fmt.Printf("第 2 行 - += 运算符实例,c 值为 = %d\n", c ) 
 c -= a 
 fmt.Printf("第 3 行 - -= 运算符实例,c 值为 = %d\n", c ) 
 c *= a 
 fmt.Printf("第 4 行 - *= 运算符实例,c 值为 = %d\n", c ) 
 c /= a 
 fmt.Printf("第 5 行 - /= 运算符实例,c 值为 = %d\n", c ) 
 c = 200 
 c <<= 2 
 fmt.Printf("第 6 行 - <<= 运算符实例,c 值为 = %d\n", c ) 
 c >>= 2 
 fmt.Printf("第 7 行 - >>= 运算符实例,c 值为 = %d\n", c ) 
 c &= 2 
 fmt.Printf("第 8 行 - &= 运算符实例,c 值为 = %d\n", c ) 
 c ^= 2 
 fmt.Printf("第 9 行 - ^= 运算符实例,c 值为 = %d\n", c ) 
 c |= 2 
 fmt.Printf("第 10 行 - |= 运算符实例,c 值为 = %d\n", c ) 
} 

以上实例运行结果:

第 1 行 - = 运算符实例,c 值为 = 21

第 2 行 - += 运算符实例,c 值为 = 42

第 3 行 - -= 运算符实例,c 值为 = 21

第 4 行 - *= 运算符实例,c 值为 = 441

第 5 行 - /= 运算符实例,c 值为 = 21

第 6 行 - <<= 运算符实例,c 值为 = 800

第 7 行 - >>= 运算符实例,c 值为 = 200

第 8 行 - &= 运算符实例,c 值为 = 0

第 9 行 - ^= 运算符实例,c 值为 = 2

第 10 行 - |= 运算符实例,c 值为 = 2

其他运算符:

测试用例

package main 
import "fmt" 
func main() { 
 var a int = 4 
 var b int32 
 var c float32 
 var ptr *int 
 /* 运算符实例 */ 
 fmt.Printf("第 1 行 - a 变量类型为 = %T\n", a ) 
 fmt.Printf("第 2 行 - b 变量类型为 = %T\n", b ) 
 fmt.Printf("第 3 行 - c 变量类型为 = %T\n", c ) 
 /* & 和 * 运算符实例 */ 
 ptr = &a /* 'ptr' 包含了 'a' 变量的地址 */ 
 fmt.Printf("a 的值为 %d\n", a)   //通过变量名称访问内存
 fmt.Printf("*ptr 为 %d\n", *ptr)   //通过地址访问内存
} 

以上实例运行结果:

第 1 行 - a 变量类型为 = int

第 2 行 - b 变量类型为 = int32

第 3 行 - c 变量类型为 = float32

a 的值为 4

*ptr 为 4

打印ab的地址

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值