我知道我可以通过反射来获取对象的值,然后使用类型断言使用以下方法来获取实际对象:
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
您还可以使用一些接口变量i
。i
的类型在编译时未知,因此编译器无法保证分配i
给s
不会破坏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配置时找
问题内容: 目前我有这样的事情 main.go 还有我的工作包 和 我正在传递给NewJob的函数是在goroutine上每2秒执行一次,但是我想访问我传递的匿名结构…但是当我尝试访问时 编号 我越来越 t.Id未定义(类型interface {}是没有方法的接口) 但是打印t给我预期的结果 {1} 问题答案: 您必须先将其声明为兼容类型,然后才能访问其字段。