Go:03---Go语言数据类型、类型检查(reflect库)、类型转换

Go:03---Go语言数据类型、类型检查(reflect库)、类型转换_第1张图片

一、Go是一种静态类型语言

  • Go是一种静态类型语言,与Python、javascript等动态语言不同
  • 静态类型:指的是错误地使用了类型时,编译器将引发错误。其优点为:
    • 性能高于动态类型语言
    • Buf通常会被编译器发现
    • 代码编辑器可提供代码补全和其他功能
    • 数据完整性更好
  • 动态类型(也叫松散类型或弱类型):为了执行程序,运行时会将一种类型转换为另一种类型。其优点为:
    • 使用动态类型语言编写软件的速度通常更快
    • 无须为执行代码而等待编译器完成编译
    • 动态类型语言通常不死板,因此有些人认为变更代码更容易
    • 有些人认为动态类型语言学习门槛更低

演示说明

  • 下面是一个简单的javascript函数,其接受两个值,将它们相加并返回。如果:
    • 调用addition(1,3),那么两个参数都会被认为为int类型,从而返回4
    • 调用addition(1,"three"),那么两个参数都会被认为为字符串类型,从而返回1three
var addition = function (a, b) {
    return x + y;
}
  • 下面是一个简单的go函数,其接受两个值,将它们相加并返回。如果:
    • 调用addition(1,3),那么函数将返回4
    • 调用addition(1,"three"),那么程序将在编译器时直接报错
func addition(x int, y int) int {
    return x + y;
}

二、布尔类型

  • 布尔类型为bool
  • 一些特点:
    • bool类型数据只允许取值true或false(默认为false)
    • 不能取值1或0
    • Go语言中不允许将整型强制转换为布尔型
    • 布尔型无法参与数值运算,也无法与其他类型进行转换
  • bool类型占1个字节

演示案例

//main.go
package main

import (
    "fmt"
)

func main() {
    var b bool
    fmt.Println(b)
    b = true
    fmt.Println(b)
}

Go:03---Go语言数据类型、类型检查(reflect库)、类型转换_第2张图片

三、整数类型

  • 整数类型有:
    • 有符号:int、int8、int16、int32、int64
    • 无符号:uint、uint8、uint16、uint32、uint64、byte
  • 一些说明与注意事项:
    • uint8与byte类型,一般用来存储单个字符
    • int16对应C语言中的short型,int64对应C语言中的long型
    • uint:32位操作系统上就是uint32,64位操作系统上就是uint64
    • int:32位操作系统上就是int32,64位操作系统上就是int64
    • uintptr:无符号整型,用于存放一个指针,是一种无符号的整数类型,没有指定具体的bit大小但是足以容纳指针。
      uintptr类型只有在底层编程是才需要,特别是Go语言和C语言函数库或操作系统接口相交互的地方
类型          描述
uint8        无符号 8位整型 (0 到 255)
uint16       无符号 16位整型 (0 到 65535)
uint32       无符号 32位整型 (0 到 4294967295)
uint64       无符号 64位整型 (0 到 18446744073709551615)
int8         有符号 8位整型 (-128 到 127)
int16        有符号 16位整型 (-32768 到 32767)
int32        有符号 32位整型 (-2147483648 到 2147483647)
int64        有符号 64位整型 (-9223372036854775808 到 9223372036854775807)

演示案例

package main

import (
    "fmt"
)

func main() {
    var num1 byte = 100
    var num2 uint8 = 100
    var num3 int16 = -1000
    var num4 int32 = 1000000000
	
    fmt.Println(num1)
    fmt.Println(num2)
    fmt.Println(num3)
    fmt.Println(num4)
}

Go:03---Go语言数据类型、类型检查(reflect库)、类型转换_第3张图片

八进制、十六进制

  • 规则如下:
    • Go语言中无法直接定义二进制数
    • 八进制以0开头
    • 十六进制以0x开头
  • 例如:
package main

import (
	"fmt"
)

func main() {
	var a int = 10
	var b int = 007
	var c int = 0xfff
	
	fmt.Printf("a(10):\n\t二进制:%b\n\t十进制:%d\n", a , a)
	fmt.Printf("b(007):\n\t十进制:%d\n\t八进制:%o\n", b , b)
	fmt.Printf("c(0xfff):\n\t十进制:%d\n\t十六进制:%x\n", c , c)
}

Go:03---Go语言数据类型、类型检查(reflect库)、类型转换_第4张图片

四、浮点数

  • Go语言支持两种浮点型数:float32和float64
  • 一些说明与注意事项:
    • golang的浮点型默认为float64类型
    • 浮点数默认为0
    • 通常情况下,应该使用float64,因为它比float32更精确
    • 0.123可以简写成.123
    • 也支持科学计数法表示:5.1234e2 等价于512.34
  • 这两种浮点型数据格式遵循IEEE 754标准:
    • float32 的浮点数的最大范围约为 3.4e38,可以使用常量定义:math.MaxFloat32
    • float64 的浮点数的最大范围约为1.8e308,可以使用一个常量定义:math.MaxFloat64

演示案例

package main

import (
	"fmt"
	"math"
)

func main() {
	var a float32 = 3.14
	var b float64 = 3.14
	
	fmt.Printf("a:%f\n", a)
	fmt.Printf("b:%f\n", b)
	fmt.Printf("float32 max:%f\n", math.MaxFloat32)
	fmt.Printf("float64 max:%f\n", math.MaxFloat64)
}

Go:03---Go语言数据类型、类型检查(reflect库)、类型转换_第5张图片

五、复数

  • 复数有实部和虚部
  • complex64:实部和虚部都为32位
  • complex128:实部和虚部都为64位

演示案例

package main

import (
	"fmt"
)

func main() {
	var c1 complex64
	c1 = 1 + 2i
	var c2 complex128
	c2 = 2 + 3i
	fmt.Println(c1)
	fmt.Println(c2)
}

Go:03---Go语言数据类型、类型检查(reflect库)、类型转换_第6张图片

六、字符

  • Golang中没有专门的字符类型,如果要存储单个字符(字母),一般使用byte来保存
  • 一些说明:
    • 字符串就是一串固定长度的字符连接起来的字符序列。Go的字符串是由单个字节连接起来的,也就是说对于传统的字符串是由字符组成的,而Go的字符串不同,它是由字节组成的
    • 字符只能被单引号包裹,不能用双引号,双引号包裹的是字符串
    • 当我们直接输出type值时,就是输出了对应字符的ASCII码值
    • 当我们希望输出对应字符,需要使用格式化输出
    • Go语言的字符使用UTF-8编码,英文字母占一个字符,汉字占三个字符
    • 在Go中,字符的本质是一个整数,直接输出时,是该字符对应的UTF-8编码的码值。
    • 可以直接给某个变量赋一个数字,然后按格式化输出时%c,会输出该数字对应的unicode字符
    • 字符类型是可以运算的,相当于一个整数,因为它们都有对应的unicode码

演示案例

package main

import (
	"fmt"
)

func main() {
	var c1 byte = 'a'
	var c2 byte = '0'
	
	//默认输出胡ASCII值
	fmt.Println(c1, c2)
	//想要输出对应字符,使%c占位符
	fmt.Printf("c1 = %c , c2 = %c", c1, c2)
}

Go:03---Go语言数据类型、类型检查(reflect库)、类型转换_第7张图片

七、rune类型

  • Go语言中的字符除了byte之外,还有一个名为rune的类型,其代表代表一个 UTF-8字符
  • 相关说明:

    • 当需要处理中文、日文或者其他复合字符时,则需要用到rune类型。rune类型实际是一个int32

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

演示案例①

package main

import (
	"fmt"
)

// 遍历字符串
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()
}

func main() {
	traversalString()
}
  • 说明:
    • 因为UTF8编码下一个中文汉字由3~4个字节组成,所以我们不能简单的按照字节去遍历一个包含中文的字符串,否则就会出现上面输出中第一行的结果
    • 字符串底层是一个byte数组,所以可以和[]byte类型相互转换。字符串是不能修改的字符串是由byte字节组成,所以字符串的长度是byte字节的长度。 rune类型用来表示utf8字符,一个rune字符由一个或多个byte组成

Go:03---Go语言数据类型、类型检查(reflect库)、类型转换_第8张图片

演示案例②

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

import (
	"fmt"
)

//修改字符串
func changeString() {
    s1 := "big"
    // 强制类型转换
    byteS1 := []byte(s1)
    byteS1[0] = 'p'
    fmt.Println(string(byteS1))

    s2 := "白萝卜"
    runeS2 := []rune(s2)
    runeS2[0] = '红'
    fmt.Println(string(runeS2))
}

func main() {
	changeString()
}

Go:03---Go语言数据类型、类型检查(reflect库)、类型转换_第9张图片

八、字符串

  • 字符串可以是任何字符序列,其中的字符可能是数字、字母和符号。例如下面是一些简单的字符串:
var str1 string = "cow"
var str2 string = "$^%$"
var str3 string = "a1234"
  • 相关说明与注意事项:
    • Go语言里的字符串的内部实现使用UTF-8编码
    • Go语言的编码都统一成了UTF-8。非常的方便,很统一,再也没有编码乱码的困扰了
    • 字符串的默认值为"",相当于定义var str string = ""
    • 字符串的类型转换,可以参阅strconv库:https://blog.csdn.net/qq_41453285/article/details/106170499

转义符

  • Go字符串也支持转义字符
  • 下面是一些常见的转义字符
转义符   含义
\r       回车符(返回行首)
\n       换行符(直接跳到下一行的同列位置)
\t       制表符
\'       单引号
\"       双引号
\\       反斜杠

字符串的两种定义形式

  • 双引号:会识别转义字符
  • 反引号(不是单引号):以字符串的原生形式输出,包括换行和特殊字符,可以实现防止攻击、输出源代码等效果
package main

import (
	"fmt"
)

func main() {
    s1 := "HelloWorld"
	s2 := `第一行
        第二行\n
        第三行\t
        `

	fmt.Println(s1)
    fmt.Println(s2)
}

 Go:03---Go语言数据类型、类型检查(reflect库)、类型转换_第10张图片

其他常用操作

len(str)                              求长度
+或fmt.Sprintf                        拼接字符串
strings.Split                         分割
strings.contains                      判断是否包含
strings.HasPrefix,strings.HasSuffix   前缀/后缀判断
strings.Index(),strings.LastIndex()   子串出现的位置
strings.Join(a[]string, sep string)   join操作
  • 当一行字符串太长时,需要使用到多行字符串,可以使用如下处理:
package main

import (
	"fmt"
)

func main() {
    //正确写法
    str := "hello" + 
        " world!"

    /*错误写法
    str := "hello "
        + "world!"
    */

    fmt.Println(str)
}

Go:03---Go语言数据类型、类型检查(reflect库)、类型转换_第11张图片

九、类型检查

  • 检查变量的类型,可以使用标准库中的reflect包,它能够让你访问变量的底层类型

演示案例

package main

import (
	"fmt"
	"reflect"
)

func main() {
    var str1 string = "Hello"
	str2 := "World"
	var i int = 10
	var f float32 = 1.2

    fmt.Println(reflect.TypeOf(str1))
	fmt.Println(reflect.TypeOf(str2))
	fmt.Println(reflect.TypeOf(i))
	fmt.Println(reflect.TypeOf(f))
}

Go:03---Go语言数据类型、类型检查(reflect库)、类型转换_第12张图片

十、类型转换

  • Golang和Java/C不同,Golang只支持显式类型转换,不支持隐式类型转换
  • 格式如下:
    • T表示要转换的类型
    • 表达式包括变量、复杂算子和函数返回值等
T(表达式)
  • 相关注意事项:
    • Go中,数据类型的转换可以是从表示范围小-->表示范围大,也可以范围大—>范围小
    • 被转换的是变量存储的数据(即值),变量本身的数据类型并没有变化
    • 在转换中,比如将int64转成int8,编译时不会报错,只是转换的结果是按溢出处理,和我们希望的结果不一样
    • 数据的转换必须显式转换,不能自动转换
    • 定义一个int8类型的整数(var num int8 = 0),如果一直自加1,这个变量的值会是(0...127 -128 -127... 0 ...127)循环往复下去,而不会超过类型最大值的范围

演示案例

package main

import (
	"fmt"
)

func main() {
    var _num int = 42
    var _float float64 = float64(_num)
    var _ui uint8 = uint8(_float)
	
    fmt.Println(_num, _float, _ui)
}

Go:03---Go语言数据类型、类型检查(reflect库)、类型转换_第13张图片

演示案例②

package main

import (
	"fmt"
)

func main() {
    var n1 int32 = 12
	var n2 int64
	var n3 int8
	
	//n2 = n1 +20 错误
	//n3 = n1 +20 错误
	
	//下面的都是正确的
	n2 = int64(n1) +20
	n3 = int8(n1) +20
	fmt.Println(n2, n3)
}

Go:03---Go语言数据类型、类型检查(reflect库)、类型转换_第14张图片

 

 

你可能感兴趣的:(Go)