初面网初面网

类型断言

类型断言(Type Assertion)用于从接口类型中提取其底层值,检查接口变量的实际类型并转换为具体类型。

基本语法

value, ok := interfaceValue.(Type)
  • interfaceValue:接口类型的变量
  • Type:想要断言的类型
  • value:断言成功后的具体类型值
  • ok:布尔值,表示断言是否成功

断言成功时 value 是实际值,ok 为 true;断言失败时 value 是 Type 的零值,ok 为 false

package main

import "fmt"

func main() {
	var i interface{} = "Hello, Go!"

	// 尝试将 i 断言为 string 类型
	if s, ok := i.(string); ok {
		fmt.Println("断言成功:", s) // 断言成功: Hello, Go!
	} else {
		fmt.Println("断言失败")
	}

	// 尝试将 i 断言为 int 类型
	if n, ok := i.(int); ok {
		fmt.Println("断言成功:", n)
	} else {
		fmt.Println("断言失败") // 断言失败
	}
}

不带 ok 的断言

另一种形式不返回布尔值,断言失败时直接触发 panic:

value := interfaceValue.(Type)
package main

import "fmt"

func main() {
	var i interface{} = "Hello, Go!"

	s := i.(string) // 断言成功
	fmt.Println("断言成功:", s)

	n := i.(int) // 断言失败,会触发 panic
	fmt.Println("断言成功:", n)
}

输出结果:

断言成功: Hello, Go!
panic: interface conversion: interface {} is string, not int

建议使用带 ok 的形式,避免断言失败导致程序崩溃

类型 switch(type switch)

使用 switch v := i.(type) 根据接口变量的实际类型执行不同逻辑:

package main

import "fmt"

func printType(i interface{}) {
	switch v := i.(type) {
	case int:
		fmt.Println("这是一个整数:", v)
	case string:
		fmt.Println("这是一个字符串:", v)
	case float64:
		fmt.Println("这是一个浮点数:", v)
	default:
		fmt.Println("未知类型")
	}
}

func main() {
	printType(42)          // 这是一个整数: 42
	printType("hello")     // 这是一个字符串: hello
	printType(3.14)        // 这是一个浮点数: 3.14
	printType([]int{1, 2}) // 未知类型
}

从接口中提取具体类型

处理接口变量时,可以先断言为具体类型再进行进一步操作:

package main

import "fmt"

func processInterface(i interface{}) {
	if s, ok := i.(string); ok {
		fmt.Println("处理字符串:", s)
	} else if n, ok := i.(int); ok {
		fmt.Println("处理整数:", n)
	} else {
		fmt.Println("无法处理的类型")
	}
}

func main() {
	processInterface("abc") // 处理字符串: abc
	processInterface(123)   // 处理整数: 123
	processInterface(1.5)   // 无法处理的类型
}

注意事项

  1. 类型断言只能用于接口类型的变量,不能用于非接口类型的变量
  2. 使用不返回布尔值的类型断言时,务必确保类型不会断言失败,否则会触发 panic
  3. 类型断言在运行时进行类型检查,会带来一定的性能开销,性能敏感场景中应谨慎使用

更新于 2026/8/13