4.6 KiB
4.6 KiB
一 数据类型转换
1.1 显式转换
Go在不同类型的变量之间赋值时需要显式转换。也就是说Golang中数据类型不能自动转换。
1.2 数值类型转换
var i int32 = 100
var n1 float64 = float64(i)
fmt.Printf("n1=%v", n1) //输出100
注意:在转换中,比如将int64
转成int8【-128---127】
,编译时不会报错,只是转换的结果是按溢出处理,和我们希望的结果不一样。 因此在转换时,需要考虑范围。
1.3 基本数据类型与字符串转换
基本数据类型转字符串:fmt.Sprintf();该函数会返回转换后的字符串
var b bool = true
var str string
str = fmt.Sprintf("%t", b)
fmt.Printf(str) //true
字符串转基本数据类型:使用包strconv
var str string = "true"
var b bool
b, _ = strconv.ParseBool(str)
fmt.Printf("%v", b)
注意:在将String
类型转成基本数据类型时,要确保String
类型能够转成有效的数据,比如可以把"123",转成一个整数,但不能转换"hello",如果这样做,Golang 直接将其转成0
,其它类型也是一样的道理,如:float => 0 bool => false
。
二 类型别名
2.1 类型别名的使用
Go在1.9版本加入了类型别名。主要用于代码升级、迁移中类型的兼容问题(C/C++中使用宏来解决重构升级带来的问题)。
Go1.9之前的版本内部定义了新的类型byte和rune,用于指代uint8
和int32
:
type byte uint8
type rune int32
Go1.9之后uint8
和int32
使用了类型别名:
type byte = uint8 // 使用 = 号定义后,都会按照等号右边的类型打印、计算
type rune = int32
类型定义是定义了一个全新的类型的类型。类型别名只是某个类型的小名,并非创造了新的类型:
type MyInt int // 类型定义
type AliasInt = int // 类型别名,支持使用括号,同时起多个别名
var a1 MyInt
fmt.Printf("a1 type: %T\n", a1) //main.MyInt
var a2 AliasInt
fmt.Printf("a2 type: %T\n", a2) //int
2.2 不同包下的类型定义
如下示例,在项目根目录新建文件夹mypack
,在该目录建立person.go
文件:
package mypack
import "fmt"
type Person struct {
}
func (p *Person)Run() {
fmt.Println("run...")
}
在main.go中,如下使用:
package main
import (
"TestGo/mypack" // // TestGo 是 go.mod文件中定义的项目名:module TestGo
"fmt"
)
type Student mypack.Person
func (s *Student) Study() {
fmt.Println("study...")
}
func main() {
s := &Student{}
s.Study()
}
2.3 不同包下的类型别名
2.2 中的案例如果将类型定义改为类型别名:
type Student = mypack.Person // 这时Student的方法就会报错:无法为 Person 添加新的方法
使用方式:必须直接在person文件中直接使用类型别名
package mypack
import "fmt"
type Person struct {
}
func (p *Person)Run() {
fmt.Println("run...")
}
type Student = Person
func (p *Student) Study() {
fmt.Println("study...")
}
main中调用别名方法:
package mypack
import "fmt"
type Person struct {
}
func (p *Person)Run() {
fmt.Println("run...")
}
type Student = Person
func (p *Student) Study() {
fmt.Println("study...")
}
三 Go的类型系统补充
3.1 命名类型和未命名类型
- 命名类型:Named Type。类型通过标识符、自定义类型表示
- 未命名类型:Unamed Type。也称为类型字面量(Type Literal),由预声明类型、关键字、操作符等组合而成,如array、slice、channel、pointer、function、未使用type定义的struct、未使用type定义的interface。
示例:
// 命名类型,其类型是 Person
type Person struct {
name string
}
// 未命名类型,其类型是 struct { name string }
p := struct {
name string
}
3.2 底层类型
所有类型都有一个底层类型 underlying type,其规则如下:
- 预声明类型(Pre-declared types)和类型字面量(type literals)的底层类型是他们自身
- 自定义类型
type newtype oldtype
中newtype的底层类型是逐层递归向下查找的,直到找到oldtype的预声明类型或字面量类型
3.3 Go中的类型相同
Go中类型相同的规范:
- 命名类型的数据类型相同:声明语句必须完全相同
- 未命名类型数据类型相同:类型声明字面量结构相同,且内部元素的类型相同
- 命名类型与未命名类型永远不同
- 通过类型别名语句声明的两个类型相同。类型别名语法:
type T1 = T2