2013-10-26 7 views
21

Есть ли способ указать значение по умолчанию в функции Go? Я пытаюсь найти это в документации, но я не могу найти ничего, что указывает, что это даже возможно.Значение по умолчанию в методе Go's

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

ответ

13

Нет, власти, которые находятся в Google, решили не поддерживать это.

https://groups.google.com/forum/#!topic/golang-nuts/-5MCaivW0qQ

+3

Также [это обсуждение с официальным заявлением] (https://groups.google.com/forum/#!msg/golang-nuts/3Go3gPNIPaw/Pv2B5udjDgMJ) и [этот связанный вопрос] (http://stackoverflow.com/вопросы/2032149/опциональные-параметры). – nemo

33

НЕТ, но есть и другие варианты реализации значения по умолчанию. Есть приблизительно good blog posts по этому вопросу, но вот некоторые конкретные примеры.


Вариант 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: Один дополнительный параметр в конце

// 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) 
} 


Option 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: Полный VARIADIC аргумент разборе (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) 
} 
+9

Какая боль. Я хотел бы, чтобы это было: 'func Concat1 (строка = 'foo', b int = 10) string {' как на большинстве других современных языков ... Это позволило бы уменьшить любой из приведенных примеров в значительной степени до одной строки кода. – Rotareti

+0

Есть ли у нас возможность написать две разные функции и оставить ее вызывающей стороне, чтобы быть явным в отношении того, что они ожидают. – ProgramCpp

1

Нет, нет способа указать значения по умолчанию. Я верю, что это сделано специально для повышения удобочитаемости, ценой немного больше времени (и, надеюсь, мысли) на конец писателя.

Я думаю, что правильный подход к тому, чтобы иметь «по умолчанию», состоит в том, чтобы иметь новую функцию, которая поставляет эту функцию по умолчанию для более общей функции. Имея это, ваш код становится более четким в ваших намерениях. Например:

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

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

С очень небольшим усилием я сделал функцию, которая выполняет обычную вещь и повторно использует общую функцию. Вы можете увидеть это во многих библиотеках, например, fmt.Println просто добавляет новую строку к тому, что в противном случае fmt.Print. Однако, читая чей-то код, ясно, что они намереваются делать с помощью функции, которую они называют. Со значениями по умолчанию я не буду знать, что должно произойти, не идя в функцию, чтобы ссылаться на то, что действительно значение по умолчанию.

Смежные вопросы