当前位置: 首页 > 面试题库 >

Golang如何为未知接口进行类型断言?

董鸣
2023-03-14
问题内容

我知道我可以通过反射来获取对象的值,然后使用类型断言使用以下方法来获取实际对象:

obj := new(User)
out := reflect.ValueOf(obj).Elem().Interface().(User)
fmt.Println(out == *obj) // true

但是,如果我不知道对象的类型是User,该怎么办呢?说它在像这样的函数中:

func Foo(obj interface{}) bool {
    // out := reflect.ValueOf(obj).Elem().Interface().( ... )
    return out == *obj
}

func main() {
    obj := new(User)
    fmt.Println(Foo(obj))
}

Foo函数内部,您将永远不知道实际上将传递哪种类型的对象,那么如何完成类型声明?


问题答案:

你不能 类型断言使您可以利用语言为您提供的静态类型检查,即使您有一个接口,其类型不是静态检查的。基本上它是这样的:

你有一些静态类型的变量s,它有型t。如果您试图像其他类型一样使用,则编译器通过拒绝编译来强制s始终具有类型的保证,因为这会破坏保证。t``s

您还可以使用一些接口变量ii的类型在编译时未知,因此编译器无法保证分配is不会破坏s具有type 的保证t。但是,您 可以
做的是类型声明。类型断言通过说:“好吧,我会在运行时检查,并且仅在类型匹配时才进行赋值”,从而避免了该问题。编译器可以这样做,因为它知道只有在类型匹配时才会发生分配,这意味着它仍然可以保证s具有type
t。因此,基本上在运行时发生的是:

if (i has type t) {
    s = i
} else {
    s = t{} // Zero value of t
}

您无法要求的原因是,编译器 必须
知道您要针对哪种类型进行检查,以便编译器可以编写我上面给出的伪代码的检查。不知道是什么t,就没有办法知道s应该是什么静态类型,也没有办法检查它是否正确。



 类似资料:
  • 问题内容: 我已经创建了一个基于字符串的角色类型,现在我想通过实现Valuer和Scanner接口使其与数据库驱动程序一起使用 我不断收到错误: 我在这里做错了什么? 问题答案: 这是第一个功能的工作代码: 尽管您可能希望使用并返回一个错误来代替恐慌。 a的签名不是您给的,而是: 请注意,这不会处理或产生NULL值。

  • 问题内容: 当使用as函数参数类型,给定非指针类型并与之一起使用时,我在Go中遇到了一个错误。 因为一段代码值得一千个单词,所以下面是一个示例: 哪个输出: 把我的结构变成一个… 稍后再读一些内容,可以解释其中的一部分,它本身就是一种类型,而不是某种无类型的容器,它解释了,以及无法获取初始类型并返回。的事实。 从文档: 要将JSON解组为接口值,Unmarshal将其中之一存储在接口值中:[…]

  • # 11.3 类型断言:如何检测和转换接口变量的类型 一个接口类型的变量 varI 中可以包含任何类型的值,必须有一种方式来检测它的 动态 类型,即运行时在变量中存储的值的实际类型。在执行过程中动态类型可能会有所不同,但是它总是可以分配给接口变量本身的类型。通常我们可以使用 类型断言 来测试在某个时刻 varI 是否包含类型 T 的值: v := varI.(T) // unchec

  • 问题内容: 在进行中,是否可以通过某种方式动态地转换变量? 例如,如果简单的转换将是: 如果我事先不知道年龄是整数怎么办?一种简单的书写方式是 有没有办法实现这样的目标?反射包提供了一些在运行时确定或强制转换类型的方法-但我找不到像上述提到的东西(适用于所有类型的通用方案)。 问题答案: 不,你不能。Go是一种静态类型的语言。变量的类型在编译时确定。 如果要动态确定的,可以使用类型切换:

  • 问题内容: 我正在使用注释设置mybatis,并获得此有用的异常 org.apache.ibatis.binding.BindingException:MapperRegistry未知类型接口org.foo.Bar 谷歌搜索找不到任何东西,也没有用户指南。我想念什么? 问题答案: 好的,知道了-这是因为我正在使用XML文件进行配置,并且为映射器本身添加了注释-并且mybatis在使用XML配置时找

  • 7.12. 通过类型断言询问行为 下面这段逻辑和net/http包中web服务器负责写入HTTP头字段(例如:"Content-type:text/html)的部分相似。io.Writer接口类型的变量w代表HTTP响应;写入它的字节最终被发送到某个人的web浏览器上。 func writeHeader(w io.Writer, contentType string) error { if