Go 语言快速入门指南:第二篇 变量与常量

简介: 变量是可以改变的,变量有自己的类型和名字,常量是一种创建命名标识符的方法,该标识符的值永远不会改变。它们还为语言提供了难以置信的灵活性。

变量

Go 语言不再像 C 和 Java 那样使用 “;” 作为程序语句的结尾。我们可以直接使用如下语法规则:

syntax_code1
syntax_code2
syntax_code3

什么是变量

变量可以从两个角度来理解:

  1. 可以改变的量,赋值一次还可以随意更改
  2. 使用多变,可以一次定义,多次使用

变量是指一个包含部分已知或未知数值或信息(即一个值)的存储地址,变量一般具有特定类型和关联名称。

package main
import "fmt"
func main() {
    var hello string = "Hello World~"
    fmt.Println("Hello, World!")
    fmt.Println(hello)
}

如上面的代码, hello 就是一个变量。

我们来拆解这变量是如何来的:

在 Go 语言中,定义变量使用 var 关键字,然后定义变量名如 hello 和类型 string ,最后给这个变量指定一个值 Hello World~ 。

所以:变量 = 变量名+类型+值

var 关键字开头,基本格式如下:

var myvariable data_type,紧接后面跟上你想定义的变量名,最后加上变量的数据类型,最后再给变量赋值,如下面的代码:

package main
import "fmt"
func main() {
    var x int
    var y int
    x = 1014
    y = 2021
    fmt.Println("x + y = ", x+y)
}

变量修改

当定义了一个变量,赋值给一个值之后,还可以对这个变量进行修改,比如:

package main
import "fmt"
func main() {
    var nickName string
    nickName = "小王"
    fmt.Println("十年前,人们叫我: ", nickName)
    // After 10 years
    nickName = "老王"
    fmt.Println("十年后,人们叫我: ", nickName)
}

同样的变量名 nickName ,在程序中使用两次,代码运行结果:

十年前,人们叫我:  小王
十年后,人们叫我:  老王

使用海象运算符定义变量

什么是海象运算符( The Walrus Operator )。因为:=很像海象——眼睛小,长着两枚长长的牙,所以这种方式叫做海象运算符,是不是很形象。


image.png

Go 语言为了方便程序员定义变量,支持使用这种海象运算符的变量命名方式,如: hello := "Hello World"

不难发现,在 := 之前并没有在程序中指定变量类型。因为我们不需要指定该类型, Go 编译器能够根据变量值推断类型,然后分配给这个变量。

例如,变量 hello 就正在分配一个字符串字面量, 变量 hello 就是字符串类型。另外,编译器可以也用 var 语句进行变量类型推导。

hello1 := "Hello World"     // 海象运算符进行的变量类型推导
var hello2 = "Hello World"  // var 关键字进行变量类型推导

可以利用 Go 的变量编写一个简单的数学相加计算,代码如下:

package main
import "fmt"
func main() {
    x := 1024
    y := 2021
    fmt.Println("x + y = ", x+y)
}


变量命名

正确命名变量是软件开发的一个重要部分。 名称必须以字母开头,并且可以包含字母数字 _(下划线)符号。 Go 编译器不关心您命名变量的名称,但是最好让变量命名描述清楚,比如名字选择 name ,比命名为 x 更好。

x := "三多"
fmt.Println("My cat's name is:", x)
name := "柚子"
fmt.Println("The other cat's name is:", name)

更改为:

catName := "三多"
fmt.Println("My cat's name is:", catName)


image.png


定义多个变量

Go 提供了定义多个变量的简写方式:

var (
  a = 3
  b = 4
  c = 5
)

常量

什么是常量

常量就是不变的量,恒定的量。Go 当然支持常量。常量的本质其实也属于基本类型,如布尔型、字符串或数字。


常量可以保证在编译阶段就计算出表达式的值,并不需要等到运行时,从而使得编译器可以在任何时候就知道这个值。


常量的创建方式与创建变量的结构相同,但我们使用 const 关键字代替 var 关键字:

package main
import "fmt"
func main() {
    const hello string = "Hello World"
    fmt.Printlb(x)
}

如果我们更改一个常量的话,比如这样:

const hello string = "Say Hello to you"
hello = "Hello, Bro"

会在编辑器中得到这样的错误,“不能给 hello 赋值(声明了常量)”:

Variables\main.go:6:8: cannot assign to hello (declared const)

常量是在程序中复用而不用每次都重新写的好方法。 例如 math 包中的圆周率 Pi 和自然常数 E 被定义为一个常数。

fmt.Println(math.E)
// 结果为:2.718281828459045

既然,我们提到了圆周率,不如来写一个程序计算一下圆的面积和周长:

package main
import (
    "fmt"
    "math"
)
func main() {
    const (
        hello string  = "Hello,"
        pi    float64 = math.Pi
    )
    var (
        name string
        r    float64
    )
    fmt.Print("Enter your name: ")
    fmt.Scanf("%s", &name)
    fmt.Println(hello + name)
    fmt.Print("让我们来学习圆,请输入圆的半径: ")
    fmt.Scanf("%f", &r)
    fmt.Printf("半径为%f的圆周长: %f\n", r, 2*pi*r)
    fmt.Printf("半径为%f的圆面积: %f", r, pi*r*r)
}

在终端中运行一下代码,如下结果:

$ go run main.go
Enter your name: Yuzhou1su
Hello,Yuzhou1su
让我们来学习圆,请输入圆的半径: 3
半径为3.000000的圆周长: 18.849556
半径为3.000000的圆面积: 28.274334

定义多个常量

跟定义多个变量一样,使用关键字 const 后跟括号,每个常量都定义在单独行上。

const (
        hello string  = "Hello,"
        pi    float64 = math.Pi
    )

常量生成器 iota

常量的声明可以使用常量生成器 iota,可以创建一系列相关的值,而不用逐个值显式写出。

iota 中,从 0 开始取值,逐个加 1,例如定义一星期,从 Sunday 开始,其值为 0。

package main
import "fmt"
type Weekday int
const (
    Sunday Weekday = iota
    Monday
    Tuesday
    Wednesday
    Thursday
    Friday
    Saturday
)
func main() {
    fmt.Printf("Sunday 是一周的第 %d 天\n", Sunday)
    fmt.Printf("Monday 是一周的第 %d 天\n", Monday)
    fmt.Printf("Tuesday 是一周的第 %d 天\n", Tuesday)
    fmt.Printf("Wednesday 是一周的第 %d 天\n", Wednesday)
    fmt.Printf("Thursday 是一周的第 %d 天\n", Thursday)
    fmt.Printf("Friday 是一周的第 %d 天\n", Friday)
    fmt.Printf("Saturday 是一周的第 %d 天", Saturday)
}

运行结果:

$ go run main.go
Sunday 是一周的第 0 天
Monday 是一周的第 1 天
Tuesday 是一周的第 2 天
Wednesday 是一周的第 3 天
Thursday 是一周的第 4 天
Friday 是一周的第 5 天
Saturday 是一周的第 6 天

无类型常量

Go 的常量有一些特别之处,上面我们定义的常量都是基本数据类型,如 stringfloat64,但许多常量并不从属于某一具体类型。编译器将这些从属类型待定的常量表示成某些值,这些值比基本类型的数字精度更高,且算数精度高于原生的机器精度。

从属待定的常量共有 6 种:

  • 无类型 布尔
  • 无类型 整数
  • 无类型 文字符号
  • 无类型 浮点数
  • 无类型 复数
  • 无类型字符串
const (
        deadbeef = 0xdeadbeef        // 无类型整数,值为 3735928559
        a        = uint32(deadbeef)  // uint32, 值为 3735928559
        b        = float32(deadbeef) // float32, 值为 3735928576(向上取整)
        c        = float64(deadbeef) // float64, 值为 3735928559
        d        = int32(deadbeef)   //  编译错误:溢出,int32无法容纳常量值
        e        = float64(1e309)    // 编译错误:溢出,float64,无法容纳常量值
        f        = uint(-1)          // 编译错误:溢出,uint 无法容纳常量值
)
// consts\main.go:31:19: constant 3735928559 overflows int32
// consts\main.go:32:21: constant 1e+309 overflows float64
// consts\main.go:33:18: constant -1 overflows uint

借助于推迟确定从属类型,无类型常量不仅能维持更高的精度,与类型已确定的常量相比,它们还能写出更多表达式而无需转换类型。

代码注释

go 语言的代码注释和 c 语言一样,使用单行注释 // 和多行注释 /**/ 的格式,在代码中适当的增加注释方便自己和他人阅读,写注释其实也是写代码前的一个总体设计。

// 声明变量
var a int
var str string
var b, c float64
// 给变量赋值
a = 20
str = "Hello World!"
b, c = 7.14, 9.14
/* 打印变量 */
fmt.Println("value of a = ", a)
fmt.Println("var of str = ", str)
fmt.Println("var of b = ", b)
fmt.Println("var of c = ", c)

总结

又到了本篇文章的总结部分。

变量是可以改变的,变量有自己的类型和名字,可以使用 var 关键字声明一个变量,或者使用短文本的海象运算符 := 来定义一个变量,变量可以隐式转换,编译器会自动推断该变量的类型,变量命名最好使用有意义方便知道大家知道其功能的名字。


常量是一种创建命名标识符的方法,该标识符的值永远不会改变。它们还为语言提供了难以置信的灵活性。在 Go 中实现常量的方式非常独特。常量不同于变量,常量只存在于编译期,无类型常量可以隐式转换,而类型常量和变量不能,无类型常量视为具有种类,而不是类型。

下一篇我们将进入真实世界的逻辑控制,体会真正的编程乐趣!

相关文章
|
1天前
|
存储 编译器 Go
Go语言学习12-数据的使用
【5月更文挑战第5天】本篇 Huazie 向大家介绍 Go 语言数据的使用,包含赋值语句、常量与变量、可比性与有序性
18 6
Go语言学习12-数据的使用
|
2天前
|
Java Go
一文带你速通go语言指针
Go语言指针入门指南:简述指针用于提升效率,通过地址操作变量。文章作者sharkChili是Java/CSDN专家,维护Java Guide项目。文中介绍指针声明、取值,展示如何通过指针修改变量值及在函数中的应用。通过实例解析如何使用指针优化函数,以实现对原变量的直接修改。作者还邀请读者加入交流群深入探讨,并鼓励关注其公众号“写代码的SharkChili”。
9 0
|
2天前
|
存储 缓存 Java
来聊聊go语言的hashMap
本文介绍了Go语言中的`map`与Java的不同设计思想。作者`sharkChili`是一名Java和Go开发者,同时也是CSDN博客专家及JavaGuide项目的维护者。文章探讨了Go语言`map`的数据结构,包括`count`、`buckets指针`和`bmap`,解释了键值对的存储方式,如何利用内存对齐优化空间使用,并展示了`map`的初始化、插入键值对以及查找数据的源码过程。此外,作者还分享了如何通过汇编查看`map`操作,并鼓励读者深入研究Go的哈希冲突解决和源码。最后,作者提供了一个交流群,供读者讨论相关话题。
10 0
|
3天前
|
Java Go
Go语言学习11-数据初始化
【5月更文挑战第3天】本篇带大家通过内建函数 new 和 make 了解Go语言的数据初始化过程
17 1
Go语言学习11-数据初始化
|
3天前
|
自然语言处理 安全 Java
速通Go语言编译过程
Go语言编译过程详解:从词法分析(生成token)到句法分析(构建语法树),再到语义分析(类型检查、推断、匹配及函数内联)、生成中间码(SSA)和汇编码。最后,通过链接生成可执行文件。作者sharkchili,CSDN Java博客专家,分享技术细节,邀请读者加入交流群。
22 2
|
4天前
|
Java Linux Go
一文带你速通Go语言基础语法
本文是关于Go语言的入门介绍,作者因其简洁高效的特性对Go语言情有独钟。文章首先概述了Go语言的优势,包括快速上手、并发编程简单、设计简洁且功能强大,以及丰富的标准库。接着,文章通过示例展示了如何编写和运行Go代码,包括声明包、导入包和输出语句。此外,还介绍了Go的语法基础,如变量类型(数字、字符串、布尔和复数)、变量赋值、类型转换和默认值。文章还涉及条件分支(if和switch)和循环结构(for)。最后,简要提到了Go函数的定义和多返回值特性,以及一些常见的Go命令。作者计划在后续文章中进一步探讨Go语言的其他方面。
10 0
|
5天前
|
JavaScript 前端开发 Go
Go语言的入门学习
【4月更文挑战第7天】Go语言,通常称为Golang,是由Google设计并开发的一种编程语言,它于2009年公开发布。Go的设计团队主要包括Robert Griesemer、Rob Pike和Ken Thompson,这三位都是计算机科学和软件工程领域的杰出人物。
13 1
|
5天前
|
Go
|
6天前
|
分布式计算 Java Go
Golang深入浅出之-Go语言中的分布式计算框架Apache Beam
【5月更文挑战第6天】Apache Beam是一个统一的编程模型,适用于批处理和流处理,主要支持Java和Python,但也提供实验性的Go SDK。Go SDK的基本概念包括`PTransform`、`PCollection`和`Pipeline`。在使用中,需注意类型转换、窗口和触发器配置、资源管理和错误处理。尽管Go SDK文档有限,生态系统尚不成熟,且性能可能不高,但它仍为分布式计算提供了可移植的解决方案。通过理解和掌握Beam模型,开发者能编写高效的数据处理程序。
134 1
|
6天前
|
算法 关系型数据库 MySQL
Go语言中的分布式ID生成器设计与实现
【5月更文挑战第6天】本文探讨了Go语言在分布式系统中生成全局唯一ID的策略,包括Twitter的Snowflake算法、UUID和MySQL自增ID。Snowflake算法通过时间戳、节点ID和序列号生成ID,Go实现中需处理时间回拨问题。UUID保证全局唯一,但长度较长。MySQL自增ID依赖数据库,可能造成性能瓶颈。选择策略时需考虑业务需求和并发、时间同步等挑战,以确保系统稳定可靠。
113 0