boards

本页内容为未名空间相应帖子的节选和存档,一周内的贴子最多显示50字,超过一周显示500字 访问原贴
Programming版 - go 的坑(转载)
相关主题
写惯了C++ code,再写C code真不习惯
最近学了一下 Go
弱问bash script, 关于IFS问题
[合集] C/C++ calling function by name
请问个c++ primer里面的小白问题.
分享:Go语言黑魔法(内存)
关于STDERR定向到文件问题
How to use a function return by reference in C++
问个C++ 编译器临时变量的问题 (转载)
为什么大家不喜欢golang的switch?
相关话题的讨论汇总
话题: nil话题: myerror话题: error话题: err话题: return
进入Programming版参与讨论
1 (共1页)
d****n
发帖数: 1637
1
献给gopher们,俺还没踩到,不过惊出一身冷汗。希望对其他gopher有用
http://studygolang.com/articles/5188
坑(s)
每种编程语言都有自己的专属坑(s),Go虽出身名门,但毕竟年轻,坑也不少,在error
处理这块也可以列出几个。
1、 Go FAQ:Why is my nil error value not equal to nil?
type MyError string
func (e *MyError) Error() string {
return string(*e)
}
var ErrBad = MyError("ErrBad")
func bad() bool {
return false
}
func returnsError() error {
var p *MyError = nil
if bad() {
p = &ErrBad
}
return p // Will always return a non-nil error.
}
func main() {
err := returnsError()
if err != nil {
fmt.Println("return non-nil error")
return
}
fmt.Println("return nil")
}
上面的输出结果是”return non-nil error”,也就是说returnsError返回后,err !=
nil。err是一个interface类型变量,其underlying有两部分组成:类型和值。只有这
两部分都为nil时,err才为nil。但returnsError返回时将一个值为nil,但类型为*
MyError的变量赋值为err,这样err就不为nil。解决方法:
func returnsError() error {
var p *MyError = nil
if bad() {
p = &ErrBad
}
return nil
}
2、switch err.(type)的匹配次序
试想一下下面代码的输出结果:
type MyError string
func (e MyError) Error() string {
return string(e)
}
func Foo() error {
return MyError("foo error")
}
func main() {
err := Foo()
switch e := err.(type) {
default:
fmt.Println("default")
case error:
fmt.Println("found an error:", e)
case MyError:
fmt.Println("found MyError:", e)
}
return
}
你可能会以为会输出:”found MyError: foo error”,但实际输出却是:”found an
error: foo error”,也就是说e先匹配到了error!如果我们调换一下次序呢:
... ...
func main() {
err := Foo()
switch e := err.(type) {
default:
fmt.Println("default")
case MyError:
fmt.Println("found MyError:", e)
case error:
fmt.Println("found an error:", e)
}
return
}
这回输出结果变成了:“found MyError: foo error”。
也许你会认为这不全是错误处理的坑,和switch case的匹配顺序有关,但不可否认的
是有些人会这么去写代码,一旦这么写,坑就踩到了。因此对于通过switch case来判
定error type的情况,将error这个“通用”类型放在后面或去掉。
f*******t
发帖数: 7549
2
我踩到了第一个坑的变种,实在恶心。
type A struct {}
func foo() *A {
return nil
}
AssertNil(interface{} o) {
if o != nil {
panic()
}
}
AssertNotNil(foo()) 会panic,因为o是(*A)(nil),跟无类型的nil不等
d****n
发帖数: 1637
3
这坑我要花好多时间才能跳出来。
谢谢分享

【在 f*******t 的大作中提到】
: 我踩到了第一个坑的变种,实在恶心。
: type A struct {}
: func foo() *A {
: return nil
: }
: AssertNil(interface{} o) {
: if o != nil {
: panic()
: }
: }

t***t
发帖数: 6066
4
感觉go很坑爹啊
T******7
发帖数: 1419
5
1 很好理解。本来就是一個interface.两部分呢。go programming lang那本书上写的
也很清楚
先在的小孩,真以为一周看看tutorial就可以写production code了?
不看2本书就写代码就是耍流氓阿。
过去老子学c++没看4,5本书都不敢说会写c++
r******t
发帖数: 250
6
看一周已写了上万行 production code,不过仔细想想确实有些困惑的地方

【在 T******7 的大作中提到】
: 1 很好理解。本来就是一個interface.两部分呢。go programming lang那本书上写的
: 也很清楚
: 先在的小孩,真以为一周看看tutorial就可以写production code了?
: 不看2本书就写代码就是耍流氓阿。
: 过去老子学c++没看4,5本书都不敢说会写c++

r******t
发帖数: 250
7
其实就是试图写这样的程序
a := nil
如果 nil 可以 polymorphic 那么接下来就有一些困惑的事情
a = &A{...}
a = &B{...}
Go 通过 typed 'nil' 避免了这个问题 但是悄悄发生的
另外发现 Go 还可以避免 a := nil 的问题 很欣慰
1 (共1页)
进入Programming版参与讨论
相关主题
为什么大家不喜欢golang的switch?
关于 exception 的一个问题
有什么办法能最快的知道那些bit是1?
char *p = "string literal"; 和 char a[] = "string liter (转载)
GO 语言里的 defer 思路是什么?
问一个Java best practices
Java的例外处理问题什么情况下不用写throws
inline functions in C++
Pattern matching
[合集] c++的题
相关话题的讨论汇总
话题: nil话题: myerror话题: error话题: err话题: return