七叶笔记 » golang编程 » GO语言数据类型及常量

GO语言数据类型及常量

目录

  1. GO语言数据类型
  2. 格式化输出
  3. 数据类型转换
  4. 常量

1、GO语言数据类型

复合数据类型这里不详细赘述,后续会有单独的文章详细讲解。

GO语言数据类型

1.1 整型

有符号整型: int8 int16 int32 int64 int

无符号整型:uint8 uint16 uint32 uint64 uint

其中uint8就是byte型,int16对应 C语言 中的short型,int64对应C语言中的long型

整型

GO语言中还有一些其他的数字类型,如下图:

其他数字类型

1.2 浮点型

Go语言提供了两种精度的复数类型:complex64和complex128,分别对应float32和float64两种浮点数精度。内置的complex函数用于构建复数,内建的real和imag函数分别返回复数的实部和虚部。

浮点型

复数也可以用==和!=进行相等比较。只有两个复数的实部和虚部都相等的时候它们才是相等的。 math/cmplx包提供了复数处理的许多函数,例如求复数的平方根函数和求幂函数。

z := x + yi
x = real(z)
y = imag(z)
 

1.3 布尔型

布尔型只有 true 和 false 两个值 ,并且布尔型无法参与计算,也不能和其他类型相互转换。

1.4 字符串类型

一个字符串是一个 不可改变 的字节序列。字符串可以包含任意的数据,包括byte值0,但是通常是用来包 含人类可读的文本。文本字符串通常被解释为采用UTF8 编码 Unicode 码点(rune)序列。

其中+操作符将两个字符串 链接 构造一个新字符串。

字符串可以用==和<进行比较;比较通过逐个字节比较完成的,因此比较的结果是字符串自然编码的顺 序。

字符串值也可以用字符串 面值 方式编写,只要将一系列字节序列包含在双引号即可。

字符串的值是不可变的 :一个字符串包含的字节序列永远不会被改变,当然我们也可以给一个字符串变 量分配一个新字符串值。

s := "left foot"
t := s
s += ", right foot"
 

这并不会导致原始的字符串值被改变,但是变量s将因为+=语句持有一个新的字符串值,但是t依然是包含原先的字符串值。

1.5 字符

字符串中的每一个元素叫“字符”,定义字符使用 单引号 ‘。GO语言中的字符有两种:

  1. byte型:uint8的别名,代表一个ASCII码字符
  2. rune型:int32的别名,代表一个UTF-8字符 ,当需要处理中文等unicode字符集时需要用到rune类型。
var a byte = 'a'
var r rune = '中'
 

2、格式化输出

golang 的fmt 包实现了格式化I/O函数,类似于C的 printf 和 scanf。格式化verb(’verb’)源自C语言但更简单。

2.1 通用

变量值和类型格式化

%v 值的默认格式表示。当输出结构体时,扩展标志(%+v)会添加字段名
%#v 值的Go语法表示
%T 值的类型的Go语法表示
%% 百分号
 

2.2 布尔值

%t 单词true或false
 

2.3 整数

%b 表示为 二进制 
%c 该值对应的unicode码值
%d 表示为十进制
%o 表示为八进制
%q 该值对应的单引号括起来的go语法字符字面值,必要时会采用安全的转义表示
%x 表示为十六进制,使用a-f
%X 表示为十六进制,使用A-F
%U 表示为Unicode格式:U+1234,等价于"U+%04X"
 

2.4 浮点数、复数的两个组分

%b 无小数部分、二进制指数的科学计数法,如-123456p-78;参strconv.FormatFloat 
%e 科学计数法,如-1234.456e+78 
%E 科学计数法,如-1234.456E+78 
%f 有小数部分但无指数部分,如123.456 
%F 等价于%f 
%g 根据实际情况采用%e或%f格式(以获得更简洁、准确的输出)
%G 根据实际情况采用%E或%F格式(以获得更简洁、准确的输出)
 

2.5 字符串和[]byte

%s 直接输出字符串或者[]byte %q 该值对应的双引号括起来的go语法字符串字面值,必要时会采用安全的转义表示
%x 每个字节用两字符十六进制数表示(使用a-f)
%X 每个字节用两字符十六进制数表示(使用A-F)
 

2.6 指针

%p 表示为十六进制,并加上前导的0x
 

没有 %u。整数如果是无符号类型自然输出也是无符号的。类似的,也没有必要指定操作数的尺寸(int8,int64)。

宽度通过一个紧跟在百分号后面的十进制数指定,如果未指定宽度,则表示值时除必需之外不作填充。精度通过(可能有的)宽度后跟点号后跟的十进制数指定。如果未指定精度,会使用默认精度;如果点号后没有跟数字,表示精度为0。举例如下:

%f: 默认宽度,默认精度
%9f 宽度9,默认精度
%.2f 默认宽度,精度2 
%9.2f 宽度9,精度2 
%9.f 宽度9,精度0
 

2.7 其它flag

+ 总是输出数值的正负号;对%q(%+q)会生成全部是ASCII字符的输出(通过转义);
- 在输出右边填充空白而不是默认的左边(即从默认的右对齐切换为左对齐);
# 切换格式:
 八进制数前加0(%#o),十六进制数前加0x(%#x)或0X(%#X),指针去掉前面的0x(%#p);
 对%q(%#q),如果strconv.CanBackquote返回真会输出反引号括起来的未转义字符串;
 对%U(%#U),如果字符是可打印的,会在输出Unicode格式、空格、单引号括起来的go字面值;
' ' 对数值,正数前加空格而负数前加负号;
对字符串采用%x或%X时(% x或% X)会给各打印的字节之间加空格;
0 使用0而不是空格填充,对于数值类型会把填充的0放在正负号后面;
 

3、数据类型转换

类型转换用于将一种数据类型的变量转换为另外一种类型的变量。Go 语言类型转换基本格式如下:

type_name(expression)
 
  • type_name 为类型,expression 为表达式,表达式包括变量、数值、函数返回值等。
  • 数据类型发生转换时需要考虑两种类型之间的关系和范围,避免发生数据截断。
  • 布尔值无法与其他数据类型进行转换。

3.1 float与 int之间的转换

需要注意float向int转换时的精度损失。

// 这个就很简单了
var a int64
a = 1
var b float64
b = 2.000
 
//a -- float64
c := float64(a)
 
// b -- int64
d := int64(b)
 

3.2 int 转 string

  • 相当于byte或rune转string
  • 如果int数值是ACSII码的编号或者unicode字符集编号,转成string本质就是根据字符集,将对应编码的字符查找出来。
  • 如果int数值超出了unicode字符集编号范围,则转成的字符串显示为乱码。
  • 例如:19968转string就是中文 “一”

【特别注意】

  • ASCII字符集中数字的10进制范围是 [30-39]
  • ASCII字符集中大写字母的10进制范围是 [65-90]
  • ASCII字符集中小写字母的10进制范围是 [97-122]
  • Unicode字符集中汉字的范围是[4e00-9fa5],10进制的范围是[19968-40869]

3.3 stirng 转 int

不允许将字符串转int

4、常量

常量是一个简单值的标识符,在程序运行时,不会被修改的量。

常量中的数据类型只可以是布尔型、数字型(整数型、浮点型和复数)和字符串型。

常量定义后未被使用不会在编译时报错。

4.1 常量的声明

常量的定义格式:

 const  identifier [type] = value
 

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

  • 显式类型定义: const b string = “abc”
  • 隐式类型定义: const b = “abc”

多个相同类型的声明可以简写为:

const c_name1, c_name2 = value1, value2
 

4.2 常量组(枚举)

常量还可以用作枚举:

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

数字 0、1 和 2 分别代表未知性别、女性和男性。

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

常量组中如果不指定类型和初始值,则与上一行非空常量的值相同。

const (
 a = 10
 b
 c 
)

// 此时 a b c的值均是 10 
 

4.3 iota

iota,特殊常量,可以认为是一个可以被编译器修改的常量。

iota 在 const关键字出现时将被重置为 0(const 内部的第一行之前),const 中每新增一行常量声明将使 iota 计数一次(iota 可理解为 const 语句块中的行索引)。

iota 可以被用作枚举值:

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

第一个 iota 等于 0,每当 iota 在新的一行被使用时,它的值都会自动加 1;所以 a=0, b=1, c=2 可以简写为如下形式:

const (
 a = iota
 b
 c
)
 

iota 用法

package main
import "fmt"
func main() {
 const (
 a = iota //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
 

再看个有趣的的 iota 实例:

package main
import "fmt"
const (
 i=1<<iota
 j=3<<iota
 k
 l
)
func main() {
 fmt.Println("i=",i)
 fmt.Println("j=",j)
 fmt.Println("k=",k)
 fmt.Println("l=",l)
}
 

以上实例运行结果为:

i= 1
j= 6
k= 12
l= 24
 

iota 表示从 0 开始自动加 1,所以 i=1<<0 , j=3<<1 << 表示左移的意思),即:i=1, j=6,这没问题,关键在 k 和 l,从输出结果看 k=3<<2 l=3<<3

简单描述下执行过程:

  • i=1 :左移 0 位,不变仍为 1;
  • j=3 :左移 1 位,变为二进制 110, 即 6;
  • k=3 :左移 2 位,变为二进制 1100, 即 12;
  • l=3 : 左移 3 位,变为二进制 11000,即 24。

这里再次说明: 常量组中如果不指定类型和初始值,则与上一行非空常量的值相同

相关文章