基本数据类型

1|0一、golang之基本数据类型

  • 共有6大基本数据类型
    • 整型
    • 浮点型
    • 复数类型
    • 布尔类型
    • 字符串类型
    • 字符相关的byte和rune类型

2|0二、整型

  • 按有无符号分为两类,说白了就是有符号的包含负数、无符号不含
  • 如有符号的int8类型范围是 (-128 到 127) 的整数,而无符号的uint8类型范围是(0~255)的整数

2|11. 有符号(范围是负数、0和正数)

  • int8、int16、int32、int64,后面的数字表示二进制时的长度

  • 其中,uint8就是我们熟知的byte型,int16对应C语言中的short型,int64对应C语言中的long型。

  • 例子: int8范围是 (-128 到 127) 的整数,负数比正数多一个

2|22. 无符号(范围是0和正数)

  • uint8、uint16、uint32、uint64

  • 例子:uint8范围是 (0 到 255) 的整数

2|33. 特殊整型

  1. uint : 32位操作系统上就是uint32,64位操作系统上就是uint64
  2. int: 32位操作系统上就是int32,64位操作系统上就是int64
  3. uintptr: 无符号整型,用于存放一个指针
  • 注意: 在使用intuint类型时,不能假定它是32位或64位的整型,而是考虑intuint可能在不同平台上的差异。

2|44. 数字字面量语法(先了解就好)

  • Go1.13版本之后引入了数字字面量语法 , 这样便于开发者以二进制、八进制或十六进制浮点数的格式定义数字 。共四种表示。

  • 实例

    1. v := 0b00101101, 代表二进制的 101101,相当于十进制的 45 2. v := 0o377,代表八进制的 377,相当于十进制的 255 3. v := 0x1p-2,代表十六进制的 1 除以 2²,也就是 0.25 4. v := 123_456 等于 123456

3|0三、浮点型

  • Go语言支持两种浮点型数:float32float64

  • 浮点型和整型的变量直接不能直接相加,需要转换一边的格式成两边相同格式,但是在一个数字表达式中,却可以直接计算

    1. 定义浮点型 package main import ( "fmt" ) func main() { a, b := 5.67, 8.97 fmt.Printf("type of a %T b %T\n", a, b) sum := a + b diff := a - b fmt.Println("sum", sum, "diff", diff) no1, no2 := 56, 89 fmt.Println("sum", no1+no2, "diff", no1-no2) } /* 打印结果: type of a float64 b float64 sum 14.64 diff -3.3000000000000007 sum 145 diff -33 */ 2. 浮点型变量和整型变量间的计算 package main import ( "fmt" ) func main() { i := 55 //int j := 67.8 //float64 sum := i + int(j) // 将j转换成int型 fmt.Println(sum) } 3. 数字表达式计算 package main import ( "fmt" ) func main() { var a = 5.9/8 // 可以这样定义 fmt.Printf("a's type %T value %v",a, a) } // 打印结果: a's type float64 value 0.7375

4|0三、复数类型

  • 分为complex64complex128
    • complex64:实部和虚部都是 float32 类型的的复数

    • complex128:实部和虚部都是 float64 类型的的复数

4|11. 定义复数

1. 内置函数 complex 用于创建一个包含实部和虚部的复数。complex 函数的语法如下: complex(x, y) // 表示定义一个实部为x,虚部为y的复数 2. 简短定义 a := 5 + 6i // 表示定义了一个实部为5,虚部为6的复数

4|22. 实例

package main import ( "fmt" ) func main() { c1 := complex(5, 7) c2 := 8 + 27i cadd := c1 + c2 fmt.Println("sum:", cadd) cmul := c1 * c2 fmt.Println("product:", cmul) } /*在上面的程序里,c1 和 c2 是两个复数。c1的实部为 5,虚部为 7。c2 的实部为8,虚部为 27。c1 和 c2 的和赋值给 `cadd` , 而 c1 和 c2 的乘积赋值给 `cmul`。该程序将输出:*/ sum: (13+34i) product: (-149+191i)

5|0四、布尔类型

  • 同其他语言一样,就是两个布尔值truefalse

  • 注意:

    • 布尔类型变量的默认值为false
    • 语言中不允许将整型强制转换为布尔型
    • 布尔型无法参与数值运算,也无法与其他类型进行转换。

6|0五、字符串类型

  • Go 语言中的字符串是一个字节切片

  • Go 中的字符串是兼容 Unicode 编码的,并且使用 UTF-8 进行编码

  • 字符串的值为双引号内的内容

  • 关于字符串的其他的操作,见下面的第六点:字符相关的byterune类型

  • Go 中的字符串是不可变的。一旦一个字符串被创建,那么它本身将无法被直接修改,但是可以通过其他方法修改

6|11. 常见的字符串转义符

转义符 解释
\r 回车符(返回首行)
\n 换行符(跳到下一行的同列位置)
\t 制表符
\' 单引号
\" 双引号
\\ 反斜杠

6|22. 多行字符串

  • 用反引号引住即可

    // 单行字符串 s1 := "字符串内容" // 多行字符串 s1 := `第一行 第二行 第三行 `
  • 反引号间换行将被作为字符串中的换行,但是所有的转义字符均无效,文本将会原样输出。

6|33. 字符串常用的方法

1|0(1)字符串长度

  • len方法返回的结果是字符串的utf8的字节长度,所以在处理当需要处理中文、日文或者其他复合字符时,会出现字符长度和字符串的字符长度不等的情况

  • 此时用 [utf8 package] 包中的 func RuneCountInString(s string) (n int) 方法用来获取字符串的长度

    • package main import ( "fmt" "unicode/utf8" ) func length(s string) { fmt.Printf("RuneCountInString 函数 求得的长度为 %s is %d\n", s, utf8.RuneCountInString(s)) } func len_get(s string) { fmt.Printf("len 函数 求得的长度为 %s is %d\n", s, len(s)) } func main() { word1 := "Señor" length(word1) len_get(word1) word2 := "Pets" length(word2) len_get(Pets) } /* RuneCountInString 函数 求得的长度为 Señor is 5 len 函数 求得的长度为 Señor is 6 RuneCountInString 函数 求得的长度为 Pets is 4 len 函数 求得的长度为 Pets is 4 */

1|0(2)其他字符串常用方法

方法 介绍
len(str) len() 返回字符串中字节的数量
+或fmt.Sprintf 拼接字符串
strings.Split 分割
strings.contains 判断是否包含
strings.HasPrefix,strings.HasSuffix 前缀/后缀判断
strings.Index(),strings.LastIndex() 子串出现的位置
strings.Join(a[]string, sep string) join操作

7|0六、字符相关的byte 和 rune类型

  • Go 语言的字符有两种 :即byte 和 rune类型

  • 字符串的每个元素就叫做字符。可以通过遍历或单个获取字符串中的字符。

  • 字符使用单引号包裹起来

  • 实例

    a := '中' b := 'x' fmt.Println(a, b) // 20013 120

7|11. byte

  • byte 型是 uint8 类型的别名,代表了ASCII码的一个字符

  • Go 使用了特殊的 rune 类型来处理 Unicode,让基于 Unicode 的文本处理更为方便,也可以使用 byte 型进行默认字符串处理,性能和扩展性都有照顾

7|22. rune

  • rune 是 Go 语言的内建类型,它也是 int32 的别称,代表一个 UTF-8字符 (注意是字符,一个汉字、一个字母都是一个字符)

  • 当需要处理中文、日文或者其他复合字符时,则需要用到rune类型

7|33. 总结(byte和rune的对比)

  • Go 使用了特殊的 rune 类型来处理 Unicode,让基于 Unicode 的文本处理更为方便,也可以使用 byte 型进行默认字符串处理,性能和扩展性都有照顾

  • 实例

    // 遍历字符串 func traversalString() { s := "hello沙河"; for i := 0; i < len(s); i++ { // byte fmt.Printf("%v(%c) ", s[i], s[i]) } fmt.Println() for _, r := range s { // rune fmt.Printf("%v(%c) ", r, r) } fmt.Println() } 打印结果: // 104(h) 101(e) 108(l) 108(l) 111(o) 230(æ) 178(²) 153() 230(æ) 178(²) 179(³) // 104(h) 101(e) 108(l) 108(l) 111(o) 27801(沙) 27827(河)
  • 因为UTF8编码下一个中文汉字由3~4个字节组成,所以我们不能简单的按照字节去遍历一个包含中文的字符串,否则就会出现上面实例中输出中第一行的结果

  • go语言的字符串和python中的字符串类似, 底层都是一个byte数组 ,所以字符串的长度就是其二进制的长度,并且他们可以直接转换成二进制格式即[]byte类型。

  • **rune类型用来表示utf8字符,一个rune字符由一个或多个byte组成 **

7|44. 遍历字符串中的单个字符

  • 由于字符串是一个字节切片,所以我们可以获取字符串的每一个字节

  • 有两种方法

    • 一个是手动转化后遍历(不转化会有bug)
    • 一个是用 for range 遍历(推荐)

1|0(1)手动转化后遍历

  • 由于go中的字符有 runebyte 类型两种,所以,有的字符在打印的时候会出现和我们预期的不符和

    • package main import ( "fmt" ) func printBytes(s string) { for i:= 0; i < len(s); i++ { fmt.Printf("%x ", s[i]) // %x 格式限定符用于指定 16 进制编码的byte类型 } } func printChars(s string) { for i:= 0; i < len(s); i++ { fmt.Printf("%c ",s[i]) // %c 格式限定符用于打印字符串的字符 } } func main() { name := "Hello World" printBytes(name) fmt.Printf("\n") printChars(name) fmt.Printf("\n") name = "Señor" printBytes(name) fmt.Printf("\n") printChars(name) } /* 打印结果 48 65 6c 6c 6f 20 57 6f 72 6c 64 H e l l o W o r l d 53 65 c3 b1 6f 72 S e à ± o r 这里的字符 ñ 在打印结果中,变成了 à ± 两个字符,在上一行的16进制编码byte类型中显示 ñ 占用了 c3 b1 两个字节,所以才打印了 à ± 两个字符 。 而我们通常预期的是:字符串中的一个字符应该就打印一个字符,这就造成了实际打印结果和我们的预期对不上 解决方法是使用 rune 类型进行字符串的转换,转换之后再进行字符的遍历,转换的代码如下 */ package main import ( "fmt" ) func printBytes(s string) { for i:= 0; i < len(s); i++ { fmt.Printf("%x ", s[i]) } } func printChars(s string) { runes := []rune(s) // 这里将字符串 s 转化成一个 rune 切片 for i:= 0; i < len(runes); i++ { fmt.Printf("%c ",runes[i]) } } func main() { name := "Hello World" printBytes(name) fmt.Printf("\n") printChars(name) fmt.Printf("\n\n") name = "Señor" printBytes(name) fmt.Printf("\n") printChars(name) } /* 打印结果,符合预期 48 65 6c 6c 6f 20 57 6f 72 6c 64 H e l l o W o r l d 53 65 c3 b1 6f 72 S e ñ o r */

1|0(2)for range 遍历

  • range 内部给我们做了转化,返回的是是当前 rune 的字节位置
  • **rune类型用来表示utf8字符,一个rune字符由一个或多个byte组成(即一个rune字符可以代表多个字节) **
package main import ( "fmt" ) func printCharsAndBytes(s string) { for index, rune_s := range s { fmt.Printf("%c starts at byte %d\n", rune_s, index) } } func main() { name := "Señor" printCharsAndBytes(name) } /* S starts at byte 0 e starts at byte 1 ñ starts at byte 2 o starts at byte 4 r starts at byte 5 o 的索引跳过了3直接变成了4,所以可以推断出 ñ 占了两个字节 */

7|55. 修改字符串

  • Go 中的字符串是不可变的。一旦一个字符串被创建,那么它将无法被修改

  • 要修改字符串,需要先将其转换成[]rune切片或[]byte切片,完成后再转换为string。无论哪种转换,都会重新分配内存,并复制字节数组

  • 实例

    func changeString() { s1 := "big" // 强制类型转换 byteS1 := []byte(s1) byteS1[0] = 'p' fmt.Println(string(byteS1)) // "pig" s2 := "白萝卜" runeS2 := []rune(s2) runeS2[0] = '红' fmt.Println(string(runeS2)) // "红萝卜" }

7|66. 构造字符串

  • 两种构造方式

    • 字节切片构造字符串

    • rune 切片构造字符串

1|0(1)字节切片构造字符串

// 构造复合字符串 Café 1. 通过16进制字节切片构造 package main import ( "fmt" ) func main() { byteSlice := []byte{0x43, 0x61, 0x66, 0xC3, 0xA9} // 用utf8的16进制的字节切片,转化成字符串 str := string(byteSlice) fmt.Println(str) // 打印结果:cafe } 2. 通过10进制字节切片构造 package main import ( "fmt" ) func main() { byteSlice := []byte{67, 97, 102, 195, 169} // 用utf8的10进制的字节切片,转化成字符串 str := string(byteSlice) fmt.Println(str) } 两个程序都输出了 字符串 Café ***********由此可见,utf8编码的不同进制数的字节切片对构造字符串无影响***********

1|0(2)rune切片构造字符串

package main import ( "fmt" ) func main() { runeSlice := []rune{0x0053, 0x0065, 0x00f1, 0x006f, 0x0072} str := string(runeSlice) fmt.Println(str) } // 在上面的程序中 runeSlice 包含字符串 Señor的 Unicode编码下的 16 进制的 字节串 。这个程序将会输出Señor

8|0七、类型转换

  • Go语言中只有强制类型转换,没有隐式类型转换。该语法只能在两个类型之间支持相互转换的时候使用

  • 强制类型转换的基本语法

    T(表达式) // T表示要转换的类型 ,表达式包括变量、复杂算子和函数返回值等.
  • 强制类型转换实例

    1.1 func sqrtDemo() { var a, b = 3, 4 var c int // math.Sqrt()接收的参数是float64类型,需要强制转换 c = int(math.Sqrt(float64(a*a + b*b))) fmt.Println(c) } 2.2 func main() { i := 10 var j float64 = float64(i) // 若没有显式转换,该语句会报错 fmt.Println("j", j) }

__EOF__

本文作者BigSun丶
本文链接https://www.cnblogs.com/Mcoming/p/11967309.html
关于博主:评论和私信会在第一时间回复。或者直接私信我。
版权声明:本博客所有文章除特别声明外,均采用 BY-NC-SA 许可协议。转载请注明出处!
声援博主:如果您觉得文章对您有帮助,可以点击文章右下角推荐一下。您的鼓励是博主的最大动力!
posted @   BigSun丶  阅读(311)  评论(0编辑  收藏  举报
编辑推荐:
· AI与.NET技术实操系列:基于图像分类模型对图像进行分类
· go语言实现终端里的倒计时
· 如何编写易于单元测试的代码
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
阅读排行:
· 25岁的心里话
· 闲置电脑爆改个人服务器(超详细) #公网映射 #Vmware虚拟网络编辑器
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· 零经验选手,Compose 一天开发一款小游戏!
· 一起来玩mcp_server_sqlite,让AI帮你做增删改查!!
点击右上角即可分享
微信分享提示