Programing

선택적 매개 변수?

lottogame 2020. 2. 22. 11:20
반응형

선택적 매개 변수?


Go에 선택적 매개 변수가 있습니까? 아니면 같은 이름과 다른 수의 인수로 두 함수를 정의 할 수 있습니까?


Go에는 선택적 매개 변수가 없으며 메서드 오버로드를 지원하지 않습니다 .

형식 일치를 수행 할 필요가없는 경우 메서드 디스패치가 단순화됩니다. 다른 언어를 사용한 경험에 따르면 이름은 같지만 서명이 다른 다양한 방법을 사용하는 것이 때로는 유용하지만 실제로는 혼란스럽고 깨지기 쉽습니다. 이름 만 일치하고 유형의 일관성을 요구하는 것은 Go의 유형 시스템에서 단순화 된 주요 결정이었습니다.


선택적 매개 변수와 같은 것을 달성하는 좋은 방법은 가변 가변 인수를 사용하는 것입니다. 이 함수는 실제로 지정한 유형의 슬라이스를받습니다.

func foo(params ...int) {
    fmt.Println(len(params))
}

func main() {
    foo()
    foo(1)
    foo(1,2,3)
}

매개 변수가 포함 된 구조체를 사용할 수 있습니다.

type Params struct {
  a, b, c int
}

func doIt(p Params) int {
  return p.a + p.b + p.c 
}

// you can call it without specifying all parameters
doIt(Params{a: 1, c: 9})

임의의 잠재적으로 많은 수의 선택적 매개 변수의 경우 기능 옵션 을 사용하는 것이 좋습니다 .

type의 Foobar경우 먼저 생성자를 하나만 작성 하십시오 .

func NewFoobar(options ...func(*Foobar) error) (*Foobar, error){
  fb := &Foobar{}
  // ... (write initializations with default values)...
  for _, op := range options{
    err := op(fb)
    if err != nil {
      return nil, err
    }
  }
  return fb, nil
}

여기서 각 옵션은 Foobar를 변경하는 기능입니다. 그런 다음 사용자가 편리한 표준 옵션을 사용하거나 만들 수있는 방법을 제공하십시오 (예 :

func OptionReadonlyFlag(fb *Foobar) error {
  fb.mutable = false
  return nil
}

func OptionTemperature(t Celsius) func(*Foobar) error {
  return func(fb *Foobar) error {
    fb.temperature = t
    return nil
  }
}

운동장

간결성을 위해 옵션 유형 ( 놀이터 )에 이름을 지정할 수 있습니다 .

type OptionFoobar func(*Foobar) error

필수 매개 변수가 필요한 경우 variadic 앞에 생성자의 첫 번째 인수로 추가하십시오 options.

기능 옵션 관용구 의 주요 이점은 다음 과 같습니다.

  • 새로운 옵션이 필요할 때 컨스트럭터 서명이 동일하게 유지되므로 기존 코드를 손상시키지 않고 시간이 지남에 따라 API가 커질 수 있습니다.
  • 기본 유스 케이스가 가장 단순합니다. 인수가 전혀 없습니다!
  • 복잡한 값의 초기화를 세밀하게 제어 할 수 있습니다.

이 기술은 Rob Pike 가 만들었 으며 Dave Cheney 도 시연했습니다 .


Go에서는 선택적 매개 변수 나 함수 오버로드가 지원되지 않습니다. Go는 다양한 수의 매개 변수를 지원합니다. 인수를 ... 매개 변수에 전달


아니요. C ++ 프로그래머를위한 이동 문서,

Go는 함수 오버로딩을 지원하지 않으며 사용자 정의 연산자를 지원하지 않습니다.

선택적 매개 변수가 지원되지 않는다는 똑같이 명확한 진술을 찾을 수 없지만 지원되지 않습니다.


아래 내용과 비슷한 기능으로 이것을 아주 잘 캡슐화 할 수 있습니다.

package main

import (
        "bufio"
        "fmt"
        "os"
)

func main() {
        fmt.Println(prompt())
}

func prompt(params ...string) string {
        prompt := ": "
        if len(params) > 0 {
                prompt = params[0]
        }
        reader := bufio.NewReader(os.Stdin)
        fmt.Print(prompt)
        text, _ := reader.ReadString('\n')
        return text
}

이 예에서 기본적으로 프롬프트에는 콜론과 그 앞에 공백이 있습니다. . .

: 

. . . 그러나 프롬프트 기능에 매개 변수를 제공하여이를 대체 할 수 있습니다.

prompt("Input here -> ")

아래와 같은 프롬프트가 나타납니다.

Input here ->

나는 params와 variadic args의 구조를 조합하여 사용했습니다. 이런 식으로 여러 서비스에서 소비 한 기존 인터페이스를 변경할 필요가 없었으며 서비스는 필요에 따라 추가 매개 변수를 전달할 수있었습니다. golang 놀이터의 샘플 코드 : https://play.golang.org/p/G668FA97Nu


나는 조금 늦었지만 유창한 인터페이스를 좋아한다면 체인 호출에 대한 세터를 다음과 같이 디자인 할 수 있습니다.

type myType struct {
  s string
  a, b int
}

func New(s string, err *error) *myType {
  if s == "" {
    *err = errors.New(
      "Mandatory argument `s` must not be empty!")
  }
  return &myType{s: s}
}

func (this *myType) setA (a int, err *error) *myType {
  if *err == nil {
    if a == 42 {
      *err = errors.New("42 is not the answer!")
    } else {
      this.a = a
    }
  }
  return this
}

func (this *myType) setB (b int, _ *error) *myType {
  this.b = b
  return this
}

그런 다음 다음과 같이 호출하십시오.

func main() {
  var err error = nil
  instance :=
    New("hello", &err).
    setA(1, &err).
    setB(2, &err)

  if err != nil {
    fmt.Println("Failed: ", err)
  } else {
    fmt.Println(instance)
  }
}

이것은 @Ripounet 답변에 제시된 기능 옵션 관용구 와 유사 하며 동일한 이점을 누리지 만 몇 가지 단점이 있습니다.

  1. 오류가 발생하면 즉시 중단되지 않으므로 생성자가 오류를 자주보고 할 경우 약간 덜 효율적입니다.
  2. err변수를 선언 하고 제로화 하는 선을 사용해야합니다.

그러나 가능한 작은 이점이 있습니다.이 유형의 함수 호출은 컴파일러가 인라인하기가 더 쉽지만 실제로는 전문가가 아닙니다.


Go 언어는 메서드 오버로딩을 지원하지 않지만 선택적 매개 변수와 같이 가변성 인수를 사용할 수 있으며 interface {}를 매개 변수로 사용할 수도 있지만 좋은 선택은 아닙니다.


맵과 함께 임의의 명명 된 매개 변수를 전달할 수 있습니다.

type varArgs map[string]interface{}

func myFunc(args varArgs) {

    arg1 := "default" // optional default value
    if val, ok := args["arg1"]; ok {
        // value override or other action
        arg1 = val.(string) // runtime panic if wrong type
    }

    arg2 := 123 // optional default value
    if val, ok := args["arg2"]; ok {
        // value override or other action
        arg2 = val.(int) // runtime panic if wrong type
    }

    fmt.Println(arg1, arg2)
}

func Test_test() {
    myFunc(varArgs{"arg1": "value", "arg2": 1234})
}

참고 URL : https://stackoverflow.com/questions/2032149/optional-parameters



반응형