Go语言之基本数据类型

Go语言之基本数据类型

文章目录

    • Go语言之基本数据类型
      • 整型
        • 特殊的整型
        • 最大与最小整型
        • 整型间的计算
      • 浮点型
        • 格式化输出
      • 复数
      • 布尔型
      • 字符串
        • 字符串切片
        • 字符串拼接
        • 字符串面值
        • Unicode
        • UTF-8
        • 字符串和byte切片
        • 常量
        • iota常量生成器

Go语言将数据类型分为四类:基础类型、复合类型、引用类型、接口类型。

基础数据类型:数字、字符串、布尔型

复合数据类型:数组、结构体

引用数据类型:指针、切片、字典、函数、通道,他们都是对程序中一个变量或状态的间接引用,即对引用类型数据的修改会影响所有该引用的拷贝

接口类型:是对其他类型行为的抽象和概括

整型

Go语言提供了有符号和无符号类型的整数运算。按照长度划分:

有符号: int8、int16、int32、in64

无符号:uint8、uint16、uint32、uint64

类型 描述
int8 有符号8位整型(-128-127)
int16 有符号16位整型(-32768-32767)
int32 有符号32位整型 (-(2^31) - (2^31-1))
int64 有符号64位整型(- (2^63)- (2^63-1))
uint8 无符号8位整型(0-255)
uint16 无符号16位整型(0-65535)
uint32 无符号32位整型 (0 - (2^32-1))
uint64 无符号64位整型 (0 - (2^64-1))
特殊的整型
类型 描述
int 应用最广泛的数据类型,32位系统int32,64位操作系统int64
uint 32位操作系统uint32,64位操作系统就是uint64
uintptr 无符号整型,适用于底层编程,存储指针
rune Unicode的rune类型等价于int32,常用来处理unicode或utf-8字符
byte byte类型等价于int8,byte用于强调数值是一个原始的数据而不是一个小的整数。常用来处理ascii字符

注:在涉及到二进制传输、读写文件的结构描述时,为了保持文件的结构不会受到不同编译目标平台字节长度影响,不要使用int和uint。

最大与最小整型

go语言中没有内置 int 类型的最大值和最小值方法

  1. 无符号整型

    • 最小值

    const UINT_MIN uint = 0

    • 最大值

    const UINT_MAX uint =^uint(0)

  2. 有符号整型

    • 最大值: 二进制补码,第一位为0 ,其余为1

      const INT_MAX = int(^uint(0)>>1)

    • 最小值:第一位为1,其余为0

      const INT_MIN = ^INT_MAX

整型间的计算

在go语言中整型不同长度之间是不允许进行计算的,比如

var i uint32 = 111
var j uint64 = 222
fmt.Println(i + j)
//会抛出异常
"invalid operation: i + j (mismatched types uint32 and uint64)"

尽管go语言提供了无符号整型,我们在编程中还是倾向于使用有符号整型,比如数组长度,虽然使用无符号更加的合理,但go的内置函数len()依然返回的是有符号整型。

	var temp = [3]int{1, 2, 3}
	for i := len(temp); i >= 0; i-- {
		fmt.Println(i)
	}

试想一下,如果len()返回的是无符号的int,那么i>=0永远为真,此循环无法结束。

无符号数往往只有在位运算或其他特殊的场景才会使用,就像bit集合、分析二进制文件格式或者哈希和加密操作等。它们通常并不用于仅仅是表达非负数量的场合。

浮点型

go语言支持两种浮点数: float32float64

取值范围在math

math.MaxFloat32  //大约 3.4e38
math.MaxFloat64  //大约 1.8e308

math.SmallestNonzeroFloat32  //大约1.40e-45
math.SmallestNonzeroFloat64	 //大约4.9e-324

float32的有效bit位只有23个,其它的bit位用于指数和符号,当整数大于23bit能表达的范围时,float32的表示将出现误差。

var f float32 = 1 << 24  
fmt.Println(f == f+1) // true
格式化输出

%g%f%e 常用浮点型打印的区别

//%g更紧凑的输出方式(无末尾0) 精度为所有数字的总数
var x = 123.45
fmt.Printf("%.4g", x) //123.5
//%f 有小数点而无指数
fmt.Printf("%6.2f", x) //123.45
//%e 科学计数法
fmt.Printf("%.4e", y) //1.2345e+02

var y = 123.56789123
// %e和%f默认精度是6
fmt.Printf("%e", y) //1.235679e+02
fmt.Printf("%f", y) //123.567891

复数

go语言提供了2种精度的复合类型:complex64和complex128。分别对应float32和float64的精度。内置的complex函数用于构建复数,real和imag函数分别返回复数的实部和虚部。对于comple64的复数,其实部和虚部都为32位。complex128实部和虚部为64位。

	//复数
	var z complex128 = complex(1, 2)
	fmt.Println(z)
	fmt.Println(real(z))
	fmt.Println(imag(z))

math.cmplx包中提供了许多复数的运算。

布尔型

布尔型的值只有true和false两种。

!true == false对于布尔型可以使用一元操作符。

布尔值也支持使用&&、|| 操作符。

与一些语言不同的是,go语言中的布尔值并不会隐式的转换成0或者1,必须使用辅助函数进行转换。

布尔值默认值是false。

字符串

go语言中的字符串的内部实现使用的是UTF-8编码。文本字符串通常被解释为采用UTF-8编码的Unicode(rune)序列。

字符串是不可改变的字节序列,也就是说字符串定义后不可以改变。不可变性使得字符串复制和切片的代价是极低的,因为他们可以底层共用数据结构。

	var str1 string = "hello world"
	str1[0] = 'w' // 编译不过,因为字符串不可改变
字符串切片

子字符串s[i:j] 是从第i位开始到第j位,左闭右开区间。如果左端省略则为0,如果右端省略则为len(s)。len() 是内部方法,返回一个字符串的长度。

	str1 := "hello world"
	fmt.Println(str1[:5]) //hello
	fmt.Println(str1[6:]) //world
	fmt.Println(str1[1:3]) //el
字符串拼接

使用+号可以对字符串进行拼接,并返回一个新的字符串。

	strLeft := "你好"
	fmt.Println(strLeft + " " + str1[:5])
字符串面值

go语言中的字符串使用双引号""来表示。

常见的转义符包含回车、换行、单双引号、制表符等

转义符 含义
\n 换行符
\r 回车符
\t 制表符
\v 垂直制表符
\’ 单引号
\" 双引号
\\ 反斜杠

多行文本使用``来表示

multiline := ` this is go
			two line
	`
Unicode

计算机早期时,使用的是7bit来表示的ASCII字符集,随着计算机的发展,需要文本表示的语言字符丰富多彩,Unicode 的出现是为了处理这些丰富多样的文本数据。

Unicode 第八版本中就收集了超过120000的字符,每个字符都分配一个唯一的Unicode码点,Unicode码点对应着go语言中的rune(int32)。

UTF-8

UTF-8是Unicode的标准,它的出现是为了解决Unicode 码点为int32 这种浪费存储空间的表示方法的。

UTF-8编码使用1-4个字节来表示每个Unicode码点,ASCII部分字符只使用1个字节,常用字符部分使用2或3个字节表示,每个符号编码后第一个字节的高端bit位用于表示编码总共有多少个字节。如果第一个字节的高端bit为0,则表示对应7bit的ASCII字符,ASCII字符每个字符依然是一个字节,和传统的ASCII编码兼容。如果第一个字节的高端bit是110,则说明需要2个字节;后续的每个高端bit都以10开头。

0xxxxxxx                             runes 0-127    (ASCII)
110xxxxx 10xxxxxx                    128-2047       (values <128 unused)
1110xxxx 10xxxxxx 10xxxxxx           2048-65535     (values <2048 unused)
11110xxx 10xxxxxx 10xxxxxx 10xxxxxx  65536-0x10ffff (other values unused)
字符串和byte切片

标准库有4个包对于字符串的处理非常重要。

  1. strings: 提供了许多如字符串查询、替换、比较、截断、拆分和合并的功能。
  2. bytes:bytes针对逐步构建字符串。
  3. strconv:提供了布尔值、整型数、浮点型和对应字符串的相互转换。
  4. unicode:提供了IsDigit、IsLetter、IsUpper和IsLower等类似功能。

strings常用方法

方法 含义
len(s) 字符串的长度
+或者fmt.Sprintf() 字符串拼接
strings.LastIndex() 、strings.Index() 子串出现的位置
strings.Split() 字符串切割
strings.Contains(s, substr string) 字串包含
strings.Join(elems []string, sep string) 字符串join
strings.Count(s, sep string) int 返回字符串中字符的个数
strings.func HasPrefix(s, prefix string) bool 前缀/后缀判断

go语言中的字符分为byte类型和rune类型

byte类型为uint8,通常用来表示一个ascii

rune 类型为int32,通常用来处理中文、日文等。

	ss := "hello 世界"
	for i := 0; i < len(ss); i++ { //byte
		fmt.Printf("%v", ss[i])
	}
	fmt.Println()
	for _, r := range ss { //rune  
		fmt.Printf("%v", r)
	}

string和byte之间的转换

	s := "abc"
	b := []byte(s)
	fmt.Println(b) //[97 98 99]
	s2 := string(b)
	fmt.Println(s2) //abc

转换的本质是 新开辟了一个字节数组来保存字符串数据的拷贝,然后引用这个底层的字节数组。以确保更改[]byte b不会引起s的改变。string(b)的操作是构造一个字符串的拷贝,以确保s2是只读的。

string和int之间的转换

	// int ->string
  x := 123
	y := fmt.Sprintf("%d", x)
	fmt.Println(y, strconv.Itoa(x)) // "123 123"
	
	// string -> int
	z, err := strconv.ParseInt(y, 10, 64) // base 10, up to 64 bits
	if err != nil {
		return
	}
	fmt.Println(z)
常量

常量表达式的值在编译期计算,而不是在运行期。每种常量的潜在类型都是基础类型:boolean、string或数字。常量值不可修改。

const pi = 3.14159
//或者定义多行
const (
    e  = 2.71828182845904523536028747135266249775724709369995957496696763
    pi = 3.14159265358979323846264338327950288419716939937510582097494459
)

定义多行常量时,除了第一行外,其他行右侧赋值都可以省略,默认使用第一行的赋值。

const (
    a = 1
    b
    c = 2
    d
)//1 1 2 2

iota常量生成器

iota 是go语言的常量计数器,只能在常量的表达式中使用。

iota在const 关键字出现时 被置为0

const中每新增一行常量声明,iota就增加1

const(
	n1 = iota //0
  n2				//1
  n3				//2
  n4				//3
)
const n5 = iota //0

你可能感兴趣的:(Go,go,go语言)