常用工具包
场景 | 对应的包 |
---|---|
格式化输出 | fmt |
字符串处理 | strings strconv |
正则表达式 | regexp |
JSON处理 | json |
文件操作 | os、io |
排序算法 | sort |
反射 | reflect |
fmt.Println()
Println()函数采用默认格式将其参数格式化并写入标准输出。
fmt.Println("id = ",s1.id, "name = ", s1.name, "sex = ", s1.sex, "age = "s1.age, "addr = ",s1.addr)
fmt.Printf()
Printf()函数根据format参数生成格式化的字符串并写入标准输出。
fmt.Printf("id = %d, name = %s, sex = %c, age = %d, addr = %s\n", s1.id, s1.name, s1.sex, s1.age, s1.addr)
格式 | 说明 | 格式 | 说明 |
---|---|---|---|
%% | 一个%字面量 | %p | 以十六进制(基数为16)表示一个值的地址,前缀为0x,字母使用小写a-f表示 |
%b | 一个二进制整数值(基数为2),或者是一个(高级的)用科学计数法表示的指数为2的浮点数 | %q | 使用Go语法及必须时使用转移,以双引号括起来的字符串或者字节切片[]byte,或者是以单引号括起来的数字 |
%c | 字符型。可以把输入的数字按照ASCII码相应转换为对应的字符 | %s | 字符串,输出字符串中的字符直至字符串中的空字符(\0) |
%d | 一个十进制数 | %t | 以true或者false输出的布尔值 |
%e | 以科学计数法e表示的浮点数或者复数值 | %T | 使用Go语法输出的值的类型 |
%E | 以科学计数法E表示的浮点数或者复数值 | %U | 一个用Unicode表示法表示的整型码点,默认值为4个数字字符 |
%f | 以标准计数法表示的浮点数或者复数值 | %v | 使用默认格式出事的内置或者自定义类型的值,或者是使用其类型的String()方式输出的自定义值,如果该方法存在的话 |
%g | 以%e或者%f表示的浮点数或者复数,任何一个都为紧凑的方式输出 | %x | 以十六进制表示整型值,数字a-f使用小写表示 |
%G | 以%E或者%f表示的浮点数或者复数,任何一个都为紧凑的方式输出 | %X | 以十六进制表示的整型值,数字A-F使用大写表示 |
%o | 一个以八进制表示的数字 |
reflect
1 反射的定义
反射就是程序能够在运行时检查变量和值,求出它们的类型。
2 反射包
在Go语言中,reflect实现了运行时 反射。reflect包会帮助识别interface{}变量的底层具体类型和值。
应用场景 | 对应的包 |
---|---|
类型 | 表示interface{}的具体类型,通过reflect.TypeOf()函数获取 |
值 | 表示interface{}的具体值,通过reflect.ValueOf()函数获取。 |
3 Go语言的反射餐定律
3.1 反射定律一
类别 | 说明 |
---|---|
定律内容 | 反射可以将“接口类型变量”转换为“反射类型对象” |
实现方式 | 通过reflect包的TypeOf和ValueOf()实现的。 |
func TypeOf(i interface{}) Type //reflect. TypeOf()函数
func ValueOf(i interface{}) Value //reflect.ValueOf()函数
package main
import (
"fmt"
"reflect"
)
type Animaler interface {
SayHi()
}
type Dog struct {
name string
weight int
}
func (d Dog) SayHi() {
fmt.Println("This is a dog")
}
func main() {
dog := Dog{"xiaoqiang", 8}
fmt.Println(reflect.ValueOf(dog))
fmt.Println(reflect.TypeOf(dog))
var a = 10
fmt.Println(reflect.TypeOf(a))
fmt.Println(reflect.ValueOf(a))
}
3.2 反射定律二
类别 | 说明 |
---|---|
定律内容 | 反射可以将“反射类型对象”转换为“接口类型变量” |
实现方式 | 根据一个reflect.Value类型的变量,使用interface方法恢复其接口类型的值; 通过断言,恢复底层的本值 |
注:这个方法会把type和value信息打包并填充到一个接口变量中,然后返回。
func (v Value) Interface() interface{} //方法v.Interface()
y := v.Interface().(float64) //断言,恢复底层的值
fmt.Println(y)
package main
import (
"fmt"
"reflect"
)
type animal interface {
sayHi()
}
type dog struct {
name string
weight int
}
func (d dog) sayHi() {
fmt.Println("This is a dog")
}
func main() {
var Dog = dog{"二哈", 50}
///返回接口变量dog 的value
v := reflect.ValueOf(Dog)
fmt.Println(v)
//将反射类型对象v转换为接口类型变量v1
v1 := v.Interface()
//类型断言,断定v1中的type = aniimal
v2 := v1.(animal)
fmt.Printf("%T %v\n", v2, v2)
fmt.Println(v2)
}
3.3 反射定律三
类别 | 说明 |
---|---|
定律内容 | 如果要修改“反射类型对象” ,其值必须是”可修改的“(settable)。 |
实现方式 | 通过反射定义一可以知道,反射对象包含了接口变量中存储的值以及类型: (1)如果反射对象中包含的值是原始值,那么可以通过反射对象修改原始值; (2)如果反射对象中包含的值不是原始值(反射对象包含的副本值或者指向原始值的地址),那么该反射对象是不可以修改的。 |
func (v Value) CanSet() bool //函数CanSet():判定反射对象是否可以修改。
func (v Value) Elem() Value //函数Elem():获取原始值对应的反射对象。
package main
import (
"fmt"
"reflect"
)
func main() {
var x = 3.4
//v1中保存的是3.4的副本,而不是x的原始空间
v1 := reflect.ValueOf(x)
fmt.Println("settability of v1:", v1.CanSet())
//v2当前把平常的x的地址,而不是x的原始空间
v2 := reflect.ValueOf(&x)
fmt.Println("settability of v2:", v2.CanSet())
//Elem用来获取原始值对应的反射对象,v3中保存的是x的原始空间*/
v3 := reflect.ValueOf(&x).Elem()
fmt.Println("settability of v3:", v3.CanSet())
v3.SetFloat(6.6) //可以修改值
fmt.Println("x=", x)
}