Go 퀴즈 Advent Calendar 2010/12/16 (wed)
문제.
package main
import "fmt"
type T struct {
x int
}
func (t T) Get() int {
return t.x
}
func (t T) Set(x int) T {
t.x = x
return t
}
func (t *T) Add(x int) *T {
t.x += x
return t
}
func main() {
var t T
fmt.Println(t.Set(1).Add(1).Get())
}
옵션
build(compile) error
panic
1
2
생각해봐!
_____ _
| ____|_ __ (_) ___ _ _
| _| | '_ \ | |/ _ \| | | |
| |___| | | || | (_) | |_| |
|_____|_| |_|/ |\___/ \__, |
|__/ _ |___/
___ ___ | |_ _(_)_ __ __ _
/ __|/ _ \| \ \ / / | '_ \ / _` |
\__ \ (_) | |\ V /| | | | | (_| |
|___/\___/|_| \_/ |_|_| |_|\__, |
____ |___/ _
/ ___| ___ __ _ _ _(_)___| |
| | _ / _ \ _____ / _` | | | | |_ / |
| |_| | (_) |_____| (_| | |_| | |/ /|_|
\____|\___/ \__, |\__,_|_/___(_)
__ _ _ __ _____ |_|____ _ __ (_)___
/ _` | '_ \/ __\ \ /\ / / _ \ '__| | / __|
| (_| | | | \__ \\ V V / __/ | | \__ \
\__,_|_| |_|___/ \_/\_/ \___|_| |_|___/
__ _| |_ | |__ ___ | |_| |_ ___ _ __ ___
/ _` | __| | '_ \ / _ \| __| __/ _ \| '_ ` _ \
| (_| | |_ | |_) | (_) | |_| || (_) | | | | | |
\__,_|\__| |_.__/ \___/ \__|\__\___/|_| |_| |_| _ _
___ / _| | |_| |__ (_)___ __ _ _ __| |_(_) ___| | ___| |
/ _ \| |_ | __| '_ \| / __| / _` | '__| __| |/ __| |/ _ \ |
| (_) | _| | |_| | | | \__ \ | (_| | | | |_| | (__| | __/_|
\___/|_| \__|_| |_|_|___/ \__,_|_| \__|_|\___|_|\___(_)
해설
A method call x.m() is valid if the method set of (the type of) x contains m and the argument list can be assigned to the parameter list of m. If x is addressable and &x's method set contains m, x.m() is shorthand for (&x).m():
x.m()
은 x 유형의 방법 집합m
을 포함하고 주어진 매개 변수 목록을 m
의 매개 변수 목록에 대입할 수 있을 때 유효하다.x
를 주소화할 수 있고 &x
의 방법집은 m
를 포함하고 x.m()
는 &x.m()
의 생략 표현이다.type T struct {
x int
}
func (t T) Get() int {
return t.x
}
func (t T) Set(x int) T {
t.x = x
return t
}
func (t *T) Add(x int) *T {
t.x += x
return t
}
func main() {
var t T
fmt.Println(t.Set(1).Add(1).Get())
}
그 중에서 다음과 같은 세 가지 방법이 호출되었다.t.Set(1)
t.Set(1).Add(1)
t.Set(1).Add(1).Get()
t.Set(1)
는 T형이고 T의 방법집에Set
가 포함되어 있어 문제가 없습니다.물론 매개 변수의 대입 가능성도 만족시켰다.두 번째
t.Set(1).Add(1)
를 보면 t.Set(1)
형T
형이기 때문에 방법팀에 호출 수신기 방법Add
이 포함되지 않는다.그럼 t.Set(1)
를 주소화한 후&t.Set(1)
의 생략 표현인가요?이를 위해t.Set(1)
반드시 주소화할 수 있어야 한다.그럼 주소화 가능성을 살펴봅시다.출처:
For an operand x of type T, the address operation &x generates a pointer of type *T to x. The operand must be addressable, that is, either a variable, pointer indirection, or slice indexing operation; or a field selector of an addressable struct operand; or an array indexing operation of an addressable array. As an exception to the addressability requirement, x may also be a (possibly parenthesized) composite literal.
이에 따라addressable의 경우 아래 5개다.
*p
t.Set(1)
이 공식은 상기 어느 것에도 적용되지 않기 때문에 주소화할 수 없다. t.Set(1).Add(1)
이런 방법은 illegal로 호출된다.따라서 본 문제의 코드는 컴파일할 수 없으며 다음과 같은 오류 정보를 출력합니다../prog.go:22:22: cannot call pointer method on t.Set(1)
./prog.go:22:22: cannot take the address of t.Set(1)
오류 메시지에는 해설 절차와 같은 내용이 적혀 있다.또한, Addrssability가 규격서에서 인용한 단락에 대한 마지막 문장은composite literal이addressble가 아니라는 것을 전제로 한다.'As an exception'은'address operator
&
에 적용되는 것은 addressable의 operand 원칙에만 해당한다'는 예외를 뜻하며,'composite literal은addressable&
적용은 아니지만'이라는 뜻이다.이것은 본 문제의 방법으로 아래의 코드를 쓰면 알 수 있다.playground 링크가 추가되었으니 확인하십시오.
T{}.Add(1) // compile error. T{}がaddressableではないから。
설명 요약
value.PointerReceiverMethod()
를(&value).PointerReceiverMethod()
로 해석한다.value
를 주소화할 수 있어야 한다.주소화가 가능한 경우는 5개다.composite literals
추가&
는 가능하지만 주소화는 불가능합니다.정답
(1) 중
compile(build) error
이 정답입니다.
Reference
이 문제에 관하여(Go 퀴즈 Advent Calendar 2010/12/16 (wed)), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다 https://zenn.dev/nobishii/articles/6699cd9451f20e텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
우수한 개발자 콘텐츠 발견에 전념 (Collection and Share based on the CC Protocol.)