Goのメソッドのデフォルト値


103

Goの関数でデフォルト値を指定する方法はありますか?ドキュメントでこれを見つけようとしていますが、これが可能であると指定するものは何も見つかりません。

func SaySomething(i string = "Hello")(string){
...
}

回答:



128

いいえ。ただし、デフォルト値を実装するための他のオプションがいくつかあります。このテーマに関するいくつかの良いブログ投稿がありますが、ここにいくつかの具体的な例があります。


**オプション1:**発信者はデフォルト値を使用することを選択します
// Both parameters are optional, use empty string for default value
func Concat1(a string, b int) string {
  if a == "" {
    a = "default-a"
  }
  if b == 0 {
    b = 5
  }

  return fmt.Sprintf("%s%d", a, b)
}

**オプション2:**最後に1つのオプションパラメータ
// a is required, b is optional.
// Only the first value in b_optional will be used.
func Concat2(a string, b_optional ...int) string {
  b := 5
  if len(b_optional) > 0 {
    b = b_optional[0]
  }

  return fmt.Sprintf("%s%d", a, b)
}

**オプション3:**構成構造体
// A declarative default value syntax
// Empty values will be replaced with defaults
type Parameters struct {
  A string `default:"default-a"` // this only works with strings
  B string // default is 5
}

func Concat3(prm Parameters) string {
  typ := reflect.TypeOf(prm)

  if prm.A == "" {
    f, _ := typ.FieldByName("A")
    prm.A = f.Tag.Get("default")
  }

  if prm.B == 0 {
    prm.B = 5
  }

  return fmt.Sprintf("%s%d", prm.A, prm.B)
}

**オプション4:**完全可変個引数引数の解析(javascriptスタイル)
func Concat4(args ...interface{}) string {
  a := "default-a"
  b := 5

  for _, arg := range args {
    switch t := arg.(type) {
      case string:
        a = t
      case int:
        b = t
      default:
        panic("Unknown argument")
    }
  }

  return fmt.Sprintf("%s%d", a, b)
}

99
なんて痛い。func Concat1(a string = 'foo', b int = 10) string {他のほとんどの現代言語と同じように...与えられた例のいずれかを1行のコードにかなり減らすことができればと思います。
ロタレティ2017

2つの異なる関数を記述し、それを呼び出し元に任せて、彼らが何を期待しているかを明示するオプションがありますか?
programCpp 2017

@ProgramCppいいえ、golangは関数のオーバーロードを許可していませんGo言語には関数/メソッドのオーバーロードがありますか?
Vusal

11

いいえ、デフォルトを指定する方法はありません。これは、読みやすさを向上させるために意図的に行われていると思いますが、ライター側ではもう少し時間(そしてできれば考えて)が犠牲になります。

「デフォルト」を持つための適切なアプローチは、そのデフォルトをより一般的な関数に提供する新しい関数を持つことだと思います。これを使用すると、コードがより明確になります。例えば:

func SaySomething(say string) {
    // All the complicated bits involved in saying something
}

func SayHello() {
    SaySomething("Hello")
}

ほんの少しの努力で、私は一般的なことをする関数を作り、一般的な関数を再利用しました。これは多くのライブラリで確認できます。fmt.Printlnたとえば、fmt.Print他の方法で行うことに改行を追加するだけです。しかし、誰かのコードを読むとき、彼らが呼び出す関数によって彼らが何をしようとしているのかは明らかです。デフォルト値では、デフォルト値が実際に何であるかを参照する関数に行かなければ、何が起こっているのかわかりません。


私はこの答えが好きで同意しますが、少なくとも彼らがそれを行うための鈍いが慣用的な方法を持っていればいいのにと思います。
サムゴメナ

15
「ちょうど別の機能を追加する」方法の爆発につながることができ、引数が複数の順列に対処するために必要な、これらの方法について、意味の発見とrememberable名の決定の負担を必要とし、対複数のメソッドを使用して、パッケージを学習に負担を追加。 もっと少なく。#jmtcw
MikeSchinkel
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.