Go에서 함수는 함수 정의의 매개 변수 목록에 지정된 유형의 인수 만받을 수 있습니다. 가변 매개 변수 언어 기능은이를 약간 복잡하게 만들지 만 잘 정의 된 규칙을 따릅니다.
의 함수 서명 fmt.Println
은 다음과 같습니다.
func Println(a ...interface{}) (n int, err error)
당 언어 specifiction ,
함수 시그니처의 최종 수신 매개 변수에는 ... 접두사가 붙은 유형이있을 수 있습니다. 이러한 매개 변수가있는 함수를 가변이라고하며 해당 매개 변수에 대해 0 개 이상의 인수를 사용하여 호출 할 수 있습니다.
즉 Println
, interface{}
유형 의 인수 목록을 전달할 수 있습니다 . 모든 유형이 빈 인터페이스를 구현하므로 모든 유형의 인수 목록을 전달할 수 있습니다 Println(1, "one", true)
. 예를 들어 오류없이 를 호출 할 수 있습니다. 언어 사양의 "... 매개 변수에 인수 전달"섹션 을 참조하십시오 .
전달 된 값은 연속 요소가 실제 인수 인 새 기본 배열이있는 [] T 유형의 새 슬라이스이며, 모두 T에 할당 할 수 있어야합니다.
문제를 일으키는 부분은 사양에서 바로 그 직후입니다.
마지막 인수가 슬라이스 유형 [] T에 할당 될 수있는 경우 인수 다음에 ...가 오면 ... T 매개 변수의 값으로 변경되지 않고 전달 될 수 있습니다.이 경우 새 슬라이스가 작성되지 않습니다.
flag.Args()
유형 []string
입니다. 이후 T
에이 Println
이다 interface{}
, []T
입니다 []interface{}
. 따라서 문제는 문자열 슬라이스 값을 인터페이스 슬라이스 유형의 변수에 할당 할 수 있는지 여부입니다. 다음과 같이 할당을 시도하여 go 코드에서 쉽게 테스트 할 수 있습니다.
s := []string{}
var i []interface{}
i = s
이러한 할당을 시도하면 컴파일러는 다음 오류 메시지를 출력합니다.
cannot use s (type []string) as type []interface {} in assignment
이것이 바로 문자열 조각 뒤에있는 줄임표를에 대한 인수로 사용할 수없는 이유 fmt.Println
입니다. 버그가 아니라 의도 한대로 작동합니다.
인쇄 할 수있는 방법의 여전히 많이 있습니다 flag.Args()
와 Println
같은이,
fmt.Println(flag.Args())
( fmt 패키지 문서에[elem0 elem1 ...]
따라 로 출력 됨 )
또는
fmt.Println(strings.Join(flag.Args(), ` `)
(각각 단일 공백으로 구분 된 문자열 슬라이스 요소를 출력합니다) 예를 들어 문자열 구분 기호가있는 문자열 패키지의 Join 함수를 사용 합니다 .
go run test.go some test flags
)를 엉망으로 만들었고flags.Args()...
그냥flag.Args()
(출력은[some test flags]
, 그 뒤에 줄 바꿈이 이어지고 실제 플래그를 등록하는 것으로도 작동하는 것처럼 보임) 변경하면 작동하는 것처럼 보였습니다. 이유를 이해하는 척하지 않을 것입니다. 그리고 Stephen의 대답은 어쨌든 훨씬 더 유익합니다. :)