酆叔のBlog

  • 首页
  • 分享技术
  • 八卦黑料
  • 生活日常
  • 日记
酆叔のBlog
上辈子作恶多端,这辈子早起上班。
  1. 首页
  2. IT技术
  3. 正文

GO 常量和变量

2024年5月15日 725点热度 0人点赞 0条评论

常量

常量的值无法在运行时改变,一旦赋值过后就无法修改,其值只能来源于:

  • 字面量
  • 其他常量标识符
  • 常量表达式
  • 结果是常量的类型转换
  • iota

常量只能是基本数据类型,不能是

  • 除基本类型以外的其它类型,如结构体,接口,切片,数组等
  • 函数的返回值

常量的声明需要用到const关键字,常量在声明时就必须初始化一个值,并且常量的类型可以省略。

iota是一个内置的常量标识符,通常用于表示一个常量声明中的无类型整数序数,一般都是在括号中使用。

常量的值无法被修改,如果尝试对其进行修改的话将会无法通过编译。

变量

变量是用于保存一个值的存储位置,允许其存储的值在运行时动态的变化。

声明

在go中的类型声明是后置的,变量的声明会用到var关键字,格式为var 变量名 类型名,变量名的命名规则必须遵守标识符的命名规则。

当要声明多个相同类型的变量时,可以只写一次类型

var numA, numB, numC int

当要声明多个不同类型的变量时,可以使用()进行包裹,可以存在多个()。

var (
    name    string
    age     int
    address string
)

var (
    school string
    class int
) 

一个变量如果只是声明而不赋值,那么变量存储的值就是对应类型的零值。

赋值

赋值会用到运算符=。

第二种方式每次都要指定类型,可以使用官方提供的语法糖:短变量初始化,可以省略掉var关键字和后置类型,具体是什么类型交给编译器自行推断。短变量初始化不能使用nil,因为nil不属于任何类型,编译器无法推断其类型。

name := "jack" // 字符串类型的变量。
name := nil // 无法通过编译

短变量声明方式无法对一个已存在的变量使用,但是有一种情况除外,那就是在赋值旧变量的同时声明一个新的变量。

// 错误示例
var a int
a := 1
// 错误示例
a := 1
a := 2

// 这种代码是可以通过编译的,变量a被重新赋值,而b是新声明的。
a := 1
a, b := 2, 2

在go语言中,有一个规则,那就是所有在函数中的变量都必须要被使用,代码只是声明了变量,但没有使用它,那么在编译时就会报错,提示变量声明了但没有使用。

这个规则仅适用于函数内的变量,对于函数外的包级变量则没有这个限制。

交换

在Go中,如果想要交换两个变量的值,不需要使用指针,可以使用赋值运算符直接进行交换。

比较

变量之间的比较有一个大前提,那就是它们之间的类型必须相同,go语言中不存在隐式类型转换。

在没有泛型之前,早期go提供的内置min,max函数只支持浮点数,到了1.21版本,go才终于将这两个内置函数用泛型重写。使用min函数比较最小值。

go中的可比较类型有

  • 布尔
  • 数字
  • 字符串
  • 指针
  • 通道 (仅支持判断是否相等)
  • 元素是可比较类型的数组(切片不可比较)
  • 字段类型都是可比较类型的结构体(仅支持判断是否相等)

除此之外,还可以通过导入标准库cmp来判断,不过仅支持有序类型的参数,在go中内置的有序类型只有数字和字符串。

代码块

在函数内部,可以通过花括号建立一个代码块,代码块彼此之间的变量作用域是相互独立的。

块与块之间的变量相互独立,不受干扰,无法访问,但是会受到父块中的影响。

输入输出

在os包下有三个外暴露的文件描述符,其类型都是*File,分别是:

  • Stdin - 标准输入
  • Stdout - 标准输出
  • Stderr - 标准错误

Go中的控制台输入输出都离不开它们。

输出

输出一句Hello 世界!,比较常用的有三种方法。

第一种是调用os.Stdout

os.Stdout.WriteString("Hello 世界!")

第二种是使用内置函数println

println("Hello 世界!")

第三种也是最推荐的一种就是调用fmt包下的Println函数

fmt.Println("Hello 世界!")

fmt.Println会用到反射,因此输出的内容通常更容易使人阅读,不过性能很差强人意。

格式化

0格式化描述接收类型
1%%输出百分号%任意类型
2%s输出string/[] byte值string,[] byte
3%q格式化字符串,输出的字符串两端有双引号""string,[] byte
4%d输出十进制整型值整型类型
5%f输出浮点数浮点类型
6%e输出科学计数法形式 ,也可以用于复数浮点类型
7%E与%e相同浮点类型
8%g根据实际情况判断输出%f或者%e,会去掉多余的0浮点类型
9%b输出整型的二进制表现形式数字类型
10%#b输出二进制完整的表现形式数字类型
11%o输出整型的八进制表示整型
12%#o输出整型的完整八进制表示整型
13%x输出整型的小写十六进制表示数字类型
14%#x输出整型的完整小写十六进制表示数字类型
15%X输出整型的大写十六进制表示数字类型
16%#X输出整型的完整大写十六进制表示数字类型
17%v输出值原本的形式,多用于数据结构的输出任意类型
18%+v输出结构体时将加上字段名任意类型
19%#v输出完整Go语法格式的值任意类型
20%t输出布尔值布尔类型
21%T输出值对应的Go语言类型值任意类型
22%c输出Unicode码对应的字符int32
23%U输出字符对应的Unicode码rune,byte
24%p输出指针所指向的地址指针类型

使用fmt.Sprintf或者fmt.Printf来格式化字符串或者输出格式化字符串。

使用其它进制时,在%与格式化动词之间加上一个空格便可以达到分隔符的效果。在使用数字时,还可以自动补零。

错误情况

格式化字符数量 < 参数列表数量

fmt.Printf("", "") //%!(EXTRA string=)

格式化字符数量 > 参数列表数量

fmt.Printf("%s%s", "") //%!s(MISSING)

类型不匹配

fmt.Printf("%s", 1) //%!s(int=1)

缺少格式化动词

fmt.Printf("%", 1) // %!(NOVERB)%!(EXTRA int=1)

输入

输入的话是通常使用fmt包下提供的三个函数

// 扫描从os.Stdin读入的文本,根据空格分隔,换行也被当作空格
func Scan(a ...any) (n int, err error) 

// 与Scan类似,但是遇到换行停止扫描
func Scanln(a ...any) (n int, err error)

// 根据格式化的字符串扫描
func Scanf(format string, a ...any) (n int, err error)

需要注意的是,Go中输入的默认分隔符号是空格。

缓冲

当对性能有要求时可以使用bufio包进行读取。

标签: GO
最后更新:2024年7月29日

酆叔

上辈子作恶多端,这辈子早起上班。

点赞
< 上一篇
下一篇 >

文章评论

razz evil exclaim smile redface biggrin eek confused idea lol mad twisted rolleyes wink cool arrow neutral cry mrgreen drooling persevering
取消回复

最新 热点 随机
最新 热点 随机
2025/05/15 周四 晴 2025/05/12 周一 晴 2025/05/08 周四 多云 2025/05/07 周三 阵雨 2025/05/06 周二 阵雨 2025/04/30 周三 多云
PHP 抽象类 GO的一些基本语法 PHP 变量赋值自增 安装MySql PHP之静态 修改数据库中所有数据表id自增为一
腾讯云
又拍云
订阅
订阅

COPYRIGHT © 2024 酆叔のBlog. ALL RIGHTS RESERVED.

Theme Kratos Made By Seaton Jiang

豫ICP备2023016219号