2017-09-03 51 views
-1

假设我们有一个函数返回一些值和一个错误。处理错误和值声明的首选方式是什么?Idiomatic Go Happy Path

func example_a(data interface{}) (interface{}, error) { 
    var err error 
    var bytes []byte 
    if bytes, err = json.Marshal(data); err != nil { 
     return nil, err 
    } 
    // ... 
    return use(bytes), nil 
} 

func example_b(data interface{}) (interface{}, error) { 
    if bytes, err := json.Marshal(data); err != nil { 
     return nil, err 
    } else { 
     // ... 
     return use(bytes), nil 
    } 
} 

func example_c(data interface{}) (result interface{}, err error) { 
    var bytes []byte 
    if bytes, err = json.Marshal(data); err != nil { 
     return 
    } 
    // ... 
    return use(bytes), nil 
} 

func example_d(data interface{}) (interface{}, error) { 
    bytes, err := json.Marshal(data) 
    if err != nil { 
     return nil, err 
    } 
    // ... 
    return use(bytes), nil 
} 

func example_dream(data interface{}) (interface{}, error) { 
    if bytes, err ≡ json.Marshal(data); err != nil { 
     return nil, err 
    } 
    // ... 
    return use(bytes), nil 
} 

实施例A是清楚的,但它增加了2个额外的行。此外,我发现目前还不清楚为什么在这种特殊情况下我们应该使用var,并且同时:=并不总是合适的。然后你想重新使用声明中的err声明,并且我不是分裂声明和分配的忠实粉丝。

实例B使用IF-申报检验的语言特性,我猜测是鼓励,但同时你不得不巢功能延续违反幸福路的原则,这也是鼓励。

实例C使用指定的参数返回的功能,这是一个在这里B.最大的问题之间的事情是,如果你的代码库是使用样式B和C,则很容易误以为:==,这会造成各种问题。

例d(从建议加)对我来说同样类型的使用问题为C的,因为不可避免地我碰到下面的:

func example_d(a, b interface{}) (interface{}, error) { 
    bytes, err := json.Marshal(a) 
    if err != nil { 
     return nil, err 
    } 

    bytes, err := json.Marshal(b) //Compilation ERROR 
    if err != nil { 
     return nil, err 
    } 

    // ... 
    return use(bytes), nil 
} 

所以依赖于先前的声明,我要修改我的代码使用:==,这使得难以看到和重构。

实例Dream是我从直觉上预期的GO - 没有嵌套,没有太多冗长和可变重用的快速退出。显然它不能编译。

通常use()被内联并重复该模式几次,复合了嵌套或分割声明问题。

那么处理这种多重返回和声明最习惯的方式是什么?有没有我失踪的模式?

+1

在这种情况下,我认为它是[example ** d **](https://play.golang.org/p/PsTBFzSWQ4)。在某些情况下,** a **有意义,** c **更少,** b **是我试图避免的。 – mkopriva

+0

看看标准库。 – Volker

+1

处理您的示例** D **的惯用方式看起来像这样https://play.golang.org/p/HhSF5BXFDb。 – mkopriva

回答

5

如果你看很多的Go代码,你会发现下面是通常的情况:

func example(data interface{}) (interface{}, error) { 
    bytes, err := json.Marshal(data) 
    if err != nil { 
     return nil, err 
    } 
    // ... 
    return use(bytes), nil 
} 

的声明,如果结构是在它的位置不错的测试,但在这里不是一般的apropriate。

+0

这个结构的问题是,你必须耍弄操作员。您离开了我为*梦想*场景准备的三线运营商,但我认为这一疏忽告诉我们 - 如果您要重复构建,那么编辑器会抱怨没有新的变量。我会编辑我的问题,希望能更好地解释。 – Gleno

+1

如果您重复使用'bytes'和'error',这在生产代码中非常罕见,它只会抱怨。重复使用err是很好的和预期的,但通常你不会重复使用你的数据值。 –