V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
The Go Programming Language
http://golang.org/
Go Playground
Go Projects
Revel Web Framework
admirez
V2EX  ›  Go 编程语言

为什么 func New(text string) error 内部是 return 一个 &errorString 而不是 errorString

  •  
  •   admirez · 2018-02-20 22:40:36 +08:00 · 1527 次点击
    这是一个创建于 2468 天前的主题,其中的信息可能已经有所发展或是发生改变。
    // New returns an error that formats as the given text.
    func New(text string) error {
    return &errorString{text}
    }

    // errorString is a trivial implementation of error.
    type errorString struct {
    s string
    }

    func (e *errorString) Error() string {
    return e.s
    }
    15 条回复    2018-02-23 21:35:32 +08:00
    majinjing3
        1
    majinjing3  
       2018-02-21 01:27:13 +08:00 via Android
    谷歌 golang receiver
    rrfeng
        2
    rrfeng  
       2018-02-21 08:32:51 +08:00 via Android
    指针效率更高
    tonic
        3
    tonic  
       2018-02-21 09:53:33 +08:00
    因为只有 `*errorString` 才有 `Error` 方法啊...
    inkedawn
        4
    inkedawn  
       2018-02-21 10:40:28 +08:00
    可以通过比较指针,来比较 error 是否相等(只要控制相同错误只创建一个 error 对象)
    否则的话,对象一复制,再比较就 false 了
    mengzhuo
        5
    mengzhuo  
       2018-02-21 11:26:22 +08:00 via iPhone
    4 楼正解
    一个是指针比较,只需要 4 个指令集,编译器可以直接 inline 到函数体中。
    而字符串比较,根据平台不同,大小和速度都不等。
    admirez
        6
    admirez  
    OP
       2018-02-21 18:19:27 +08:00
    @tonic 可是把 func (e *errorString) Error() string 改成 func (e errorString) Error() string 一样可以输出 error 啊
    douglarek
        7
    douglarek  
       2018-02-21 19:09:32 +08:00
    @admirez 不是这样说的;你改成 func (e errorString) Error() string 一样输出不能说明说明,因为 非指针 receiver 可以转化默认转化成 receiver, 所以可以输出
    douglarek
        8
    douglarek  
       2018-02-21 19:10:11 +08:00
    @admirez 不是这样说的;你改成 func (e errorString) Error() string 一样输出不能说明什么,因为 非指针 receiver 可以默认转化成 receiver, 所以可以输出
    douglarek
        9
    douglarek  
       2018-02-21 19:11:42 +08:00
    fengzixu
        10
    fengzixu  
       2018-02-22 08:11:41 +08:00
    golang 中的 reciver,其实只是形式上让我们看起来像是某个类型的方法而已。但实际上,reciver 也是被当做函数参数列表中的第一个参数传递到函数内部的。换句话说,reciver 和其他在形参列表中的参数是没有任何区别的。

    ```
    func (e *errorString) Error() string
    ```
    上面这个函数可以转换为

    ```
    func Error(e *errorString) string
    ```
    golang 中的函数签名是和形参列表相关的,这一点在 C++中也是有体现的。比如多个构造函数可以带上不同的参数或者不带参数,虽然函数名都一样,但实际上函数签名还是不同的。
    所以,如果想在外面输出 errorString 类型对象的内容进而调用 Error 方法,就必须返回&errorString
    fengzixu
        11
    fengzixu  
       2018-02-22 08:12:55 +08:00
    更正一下:receiver
    BBCCBB
        12
    BBCCBB  
       2018-02-22 08:49:28 +08:00
    4l 正解
    picasso250
        13
    picasso250  
       2018-02-22 15:30:02 +08:00
    3L 正解

    看清楚这里的星号!
    func (e *errorString) Error() string {
    return e.s
    }
    tonic
        14
    tonic  
       2018-02-22 20:30:14 +08:00
    @admirez 尴尬了, 跟 interface 那个 pointer receiver 搞混了嘻嘻嘻
    iRiven
        15
    iRiven  
       2018-02-23 21:35:32 +08:00 via Android
    只有指针能和 nil 比较我是这么理解的
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   2735 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 33ms · UTC 07:05 · PVG 15:05 · LAX 23:05 · JFK 02:05
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.