类型断言用于从接口值中提取具体的类型。本章将详细介绍类型断言的使用方法。
类型断言是检查接口值是否包含特定类型的操作。
类型断言示意:
接口值 (type, value)
↓
类型断言
↓
具体类型值
值 := 接口.(类型)
值, ok := 接口.(类型)
package main
import "fmt"
func main() {
var i interface{} = "hello"
s := i.(string)
fmt.Printf("字符串: %s\n", s)
n := i.(int)
fmt.Println(n)
}
直接断言失败会 panic,不推荐使用。
package main
import "fmt"
func main() {
var i interface{} = "hello"
s, ok := i.(string)
if ok {
fmt.Printf("字符串: %s\n", s)
} else {
fmt.Println("不是字符串")
}
n, ok := i.(int)
if ok {
fmt.Printf("整数: %d\n", n)
} else {
fmt.Println("不是整数")
}
}
使用 switch 语句检查多种类型:
package main
import "fmt"
func TypeCheck(v interface{}) {
switch t := v.(type) {
case int:
fmt.Printf("整数: %d\n", t)
case string:
fmt.Printf("字符串: %s\n", t)
case bool:
fmt.Printf("布尔: %t\n", t)
case float64:
fmt.Printf("浮点数: %f\n", t)
case []int:
fmt.Printf("整数切片: %v\n", t)
case map[string]int:
fmt.Printf("Map: %v\n", t)
default:
fmt.Printf("未知类型: %T\n", t)
}
}
func main() {
TypeCheck(42)
TypeCheck("hello")
TypeCheck(true)
TypeCheck(3.14)
TypeCheck([]int{1, 2, 3})
TypeCheck(map[string]int{"a": 1})
TypeCheck(struct{}{})
}
package main
import "fmt"
type Person struct {
Name string
Age int
}
func main() {
var i interface{} = Person{Name: "张三", Age: 25}
p, ok := i.(Person)
if ok {
fmt.Printf("姓名: %s, 年龄: %d\n", p.Name, p.Age)
}
}
package main
import "fmt"
type Person struct {
Name string
Age int
}
func main() {
var i interface{} = &Person{Name: "张三", Age: 25}
p, ok := i.(*Person)
if ok {
fmt.Printf("姓名: %s, 年龄: %d\n", p.Name, p.Age)
}
p2, ok := i.(Person)
fmt.Printf("值类型断言: %v\n", ok)
}
package main
import "fmt"
type Reader interface {
Read() string
}
type Writer interface {
Write(string)
}
type ReadWriter interface {
Reader
Writer
}
type File struct {
content string
}
func (f *File) Read() string {
return f.content
}
func (f *File) Write(s string) {
f.content = s
}
func main() {
var rw ReadWriter = &File{}
r, ok := rw.(Reader)
fmt.Printf("是 Reader: %v\n", ok)
fmt.Println(r.Read())
w, ok := rw.(Writer)
fmt.Printf("是 Writer: %v\n", ok)
w.Write("hello")
}
package main
import (
"encoding/json"
"fmt"
)
func ParseJSON(data []byte) {
var result interface{}
json.Unmarshal(data, &result)
switch v := result.(type) {
case map[string]interface{}:
fmt.Println("JSON 对象:")
for key, val := range v {
fmt.Printf(" %s: %v\n", key, val)
}
case []interface{}:
fmt.Println("JSON 数组:")
for i, val := range v {
fmt.Printf(" [%d]: %v\n", i, val)
}
default:
fmt.Printf("其他类型: %T\n", v)
}
}
func main() {
obj := `{"name": "张三", "age": 25}`
ParseJSON([]byte(obj))
arr := `[1, 2, 3, "four", true]`
ParseJSON([]byte(arr))
}
package main
import (
"fmt"
"os"
)
func main() {
_, err := os.Open("nonexistent.txt")
if err != nil {
switch e := err.(type) {
case *os.PathError:
fmt.Printf("路径错误: %s\n", e.Path)
case *os.LinkError:
fmt.Printf("链接错误: %s -> %s\n", e.Old, e.New)
default:
fmt.Printf("其他错误: %v\n", e)
}
}
}
package main
import "fmt"
func Process(v interface{}) {
switch t := v.(type) {
case int:
fmt.Printf("整数翻倍: %d\n", t*2)
case string:
fmt.Printf("字符串长度: %d\n", len(t))
case []int:
sum := 0
for _, n := range t {
sum += n
}
fmt.Printf("切片求和: %d\n", sum)
default:
fmt.Printf("不支持的类型: %T\n", t)
}
}
func main() {
Process(10)
Process("hello")
Process([]int{1, 2, 3, 4, 5})
Process(3.14)
}
本章学习了 Go 语言的类型断言:
| 知识点 | 说明 |
|---|---|
| 基本断言 | v.(Type) |
| 安全断言 | v, ok := i.(Type) |
| 类型切换 | switch v := i.(type) |
| 接口断言 | 断言接口类型 |