MST

星途 面试题库

面试题:Go语言中Go接口的动态类型与静态类型在赋值场景下的区别

在Go语言中,假设有一个接口类型`interfaceA`和两个实现了该接口的结构体类型`structB`和`structC`。请阐述将`structB`和`structC`类型的实例赋值给`interfaceA`类型变量时,动态类型和静态类型分别是什么,以及它们在后续使用中的表现有何不同。
24.7万 热度难度
编程语言Go

知识考点

AI 面试

面试题答案

一键面试
  1. 动态类型和静态类型
    • 当将structB类型的实例赋值给interfaceA类型变量时:
      • 静态类型interfaceA。因为变量在声明时的类型是interfaceA,这就是其静态类型。
      • 动态类型structB。由于实际存储在接口变量中的值是structB类型的实例,所以structB是动态类型。
    • 当将structC类型的实例赋值给interfaceA类型变量时:
      • 静态类型:同样是interfaceA。变量声明类型决定了静态类型。
      • 动态类型structC。因为实际存储的值是structC类型的实例。
  2. 后续使用中的表现
    • 方法调用
      • 无论动态类型是structB还是structC,都只能调用interfaceA接口中定义的方法。因为编译器在编译时只知道变量的静态类型interfaceA,所以只能确保接口中定义的方法可以被调用。例如,如果interfaceA定义了Method1方法,那么无论是interfaceA变量持有structB还是structC实例,都可以通过该变量调用Method1方法。
      • 但是,如果structBstructC有各自特有的方法(未在interfaceA中定义),通过interfaceA类型变量是无法直接调用这些特有方法的。比如structBSpecialMethodForB方法,即使interfaceA变量持有structB实例,也不能直接用该变量调用SpecialMethodForB方法。
    • 类型断言
      • 可以使用类型断言来获取接口变量的动态类型。例如,对于持有structB实例的interfaceA变量i,可以通过b, ok := i.(structB)来进行类型断言,若oktrue,则b就是实际的structB类型值,可以访问structB特有的方法和字段。对于持有structC实例的情况同理。
      • 类型断言在运行时检查动态类型是否符合断言的类型,如果不符合,对于非空接口,类型断言会返回一个零值和false;对于空接口,会触发panic
    • 接口比较
      • 两个接口值比较时,如果它们的动态类型相同且动态值也相等(对于可比较类型,如基本类型、指针等,按照相应规则比较;对于自定义结构体,如果其所有字段可比较且对应字段相等,则结构体相等),则两个接口值相等。例如,如果两个interfaceA类型变量分别持有structB实例,且这两个structB实例的所有字段值都相等,那么这两个接口值相等。如果动态类型不同,即使它们实现了相同的接口,接口值也不相等。