英文:
Why type assertion of an interface equal to nil in type switch non-nil branch?
问题
给定的代码如下:
type Int struct {
v int
}
func typeAssert(val any) {
switch v := val.(type) {
case nil:
fmt.Println("val type is nil")
case *Int:
fmt.Println("val type is *Int")
if v == nil {
fmt.Println("val after type assertion is nil?")
}
}
}
func main() {
var i1 *Int
typeAssert(i1)
}
输出结果为:
val type is *Int
val after type assertion is nil?
我感到困惑的是,既然在switch v := val.(type)中匹配到了*Int,为什么v == nil会为true?如果v == nil为true,那么case nil应该也能匹配,但实际上并没有匹配到。
英文:
Given the codes
type Int struct {
v int
}
func typeAssert(val any) {
switch v := val.(type) {
case nil:
fmt.Println("val type is nil")
case *Int:
fmt.Println("val type is *Int")
if v == nil {
fmt.Println("val after type assertion is nil?")
}
}
}
func main() {
var i1 *Int
typeAssert(i1)
}
Output:
val type is *Int
val after type assertion is nil?
What confuses me is that since the *Int is matched in switch v := val.(type), why could the v == nil be true? If the v == nil be true, the case nil could be matched, actually, it does not.
答案1
得分: 1
因为有两种带有接口值的nil:
- 一个
nil接口,会触发类型切换的第一个分支。就像var x interface{} = nil一样-不仅值是nil,类型也是nil。 - 一个
nil值,比如var x interface = (nil)(*Int)。这会触发第二个分支,因为它有一个类型,类型与switch中的类型匹配,但值是nil。在代码中,v是一个值为nil的*Int。
英文:
Because there are two kinds of nil with an interface value:
- A
nilinterface, which would hit the first branch of your type switch. This is likevar x interface{} = nil- not only is the valuenil, the type is alsonil. - A
nilvalue, likevar x interface = (nil)(*Int). This hits the second branch, because it has a type, the type matches the type in theswitch, but the value isnil. In the code,vis a*Intwhose value isnil.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。


评论