선택적 매개 변수?
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 답변에 제시된 기능 옵션 관용구 와 유사 하며 동일한 이점을 누리지 만 몇 가지 단점이 있습니다.
- 오류가 발생하면 즉시 중단되지 않으므로 생성자가 오류를 자주보고 할 경우 약간 덜 효율적입니다.
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
'Programing' 카테고리의 다른 글
삭제 된 원격 브랜치로 원점에서 가져 오시겠습니까? (0) | 2020.02.22 |
---|---|
파이썬 소스에서 UTF-8 인코딩으로 작업하기 (0) | 2020.02.22 |
반복자, 반복 가능 및 반복은 정확히 무엇입니까? (0) | 2020.02.22 |
JavaScript에서 [1,2] + [3,4] = "1,23,4"인 이유는 무엇입니까? (0) | 2020.02.22 |
RadioButton을 열거 형에 바인딩하는 방법은 무엇입니까? (0) | 2020.02.22 |