“点括号”语法的含义是什么?

113

我正在学习一个样例Go应用程序,它将数据存储在mongodb中。这一行代码(https://github.com/zeebo/gostbook/blob/master/context.go#L36)似乎访问了gorilla session中存储的用户ID:

if uid, ok := sess.Values["user"].(bson.ObjectId); ok {
  ...
}

有人可以解释一下这里的语法吗?我知道 sess.Values["user"] 从会话中获取一个值,但是后面的部分是什么意思?为什么点号后面的表达式要用括号括起来?这是函数调用吗?

1个回答

152
sess.Values["user"] 是一个 interface{},圆括号中的内容称为 类型断言。它检查 sess.Values["user"] 的值是否为 bson.ObjectId 类型。如果是,则 ok 将为 true。否则,它将为 false
例如:
var i interface{}
i = int(42)

a, ok := i.(int)
// a == 42 and ok == true

b, ok := i.(string)
// b == "" (default value) and ok == false

12
值得一提的是,用于类型断言的惯用语被称为“comma ok”(if value, ok := try_to_obtain_value(); ok { ...),并且在《Effective Go》中有解释,其中包括名为“Maps”的部分。值得一提的是,对于任何想成为 Gopher 的人来说,这整个文档都是必读的。 - kostix
12
值得一提的是,尽管 b, ok := i.(string) 的行为类似于 _TryAssert_,b := i.(string) 如果断言无效将立即引发 panic。 - stratovarius
谢谢,那 sess.Values["user"].(type) 这个是返回类型,对吧? - tim
说实话,这是一个有些有用的答案,@kostix关于“逗号OK”的评论也很有帮助。但它没有像用户的示例那样充分发展接口方面。我很快就能自己做到这一点,但由于这个问题已经关闭了,所以我会把它留在那里。 - Oliver Williams

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接