var dataSlice []int = []int{1, 2, 3}
var interfaceSlice []interface{} = dataSlice
cannot use dataSlice (type []int) as type []interface {} in assignment
[]interface{}
는 인터페이스가 아닙니다.[]interface{}
는 각 element타입이 interface{}인 slice 입니다.interface{}
은 두 Word를 차지하는데,
Word 하나는 포함된 데이터의 타입을 표현하기 위해 쓰이고
다른 Word는 포함된 데이터 혹은 포인터를 위해 쓰입니다.[]interface{}
는 Nx2 Word 길이의 데이터를 가지고
있습니다.[]int
는 길이 N의 slice []int
의 길이는 N * sizeof(int)의 길이만큼 데이터를
가지고 있습니다.[]int
를 []interface{}
로 할당할 수 없습니다.func main() {
PrintMemUsage()
var dataSlice []int64 = make([]int64, 0, 1024*1024/8)
PrintMemUsage()
runtime.GC()
var interfaceSlices []interface{} = make([]interface{}, 0, 1024*1024/8)
PrintMemUsage()
_ = dataSlice
_ = interfaceSlices
}
func PrintMemUsage() {
var m runtime.MemStats
runtime.ReadMemStats(&m)
fmt.Printf("Alloc = %v MiB", byteToMegaByte(m.Alloc))
fmt.Printf("\tTotalAlloc = %v MiB", byteToMegaByte(m.TotalAlloc))
fmt.Printf("\tSys = %v MiB", byteToMegaByte(m.Sys))
fmt.Printf("\tNumGC = %v\n", m.NumGC)
}
func byteToMegaByte(b uint64) uint64 {
return b / 1024 / 1024
}
Alloc = 0 MiB TotalAlloc = 0 MiB Sys = 66 MiB NumGC = 0
Alloc = 1 MiB TotalAlloc = 1 MiB Sys = 68 MiB NumGC = 0
Alloc = 2 MiB TotalAlloc = 3 MiB Sys = 68 MiB NumGC = 1
1MB
가 할당 되어 있습니다.2MB
가
할당된 것을 확인할 수 있었습니다.dataSlice
의 타입을 interface{}
로 사용하는 방법이 있습니다.var dataSlice []int = foo()
var interfaceSlice []interface{} = make([]interface{}, len(dataSlice))
for i, d := range dataSlice {
interfaceSlice[i] = d
}
type Duck interface {
quack()
}
type DonaldDuck struct {
}
func (donald DonaldDuck) quack() {
fmt.Println("Quack!")
}
func quack(duck Duck) {
duck.quack()
}
Duck
라는 인터페이스는 quack()
라는 메소드를 가지고 있습니다.DonaldDuck
타입은 quack()
메소드를 구현하고 있으므로 Duck
인터페이스를
구현하고 있습니다.DonaldDuck
의 인스턴스가 포인터이든 아니든 상관없이 다음 테스트는
통과합니다.func ExampleQuack() {
donaldDuck := DonaldDuck{}
quack(donaldDuck)
pointerDonaldDuck := &DonaldDuck{}
quack(pointerDonaldDuck)
// Output:
// Quack!
// Quack!
}
Ran 0 of 0 Specs in 0.000 seconds
SUCCESS! -- 0 Passed | 0 Failed | 0 Pending | 0 Skipped
--- PASS: TestSliceInterface (0.00s)
=== RUN ExampleQuack
--- PASS: ExampleQuack (0.00s)
PASS
ok go-test/interface/slice_interface 0.013s
DonaldDuck
가 quack()
을 포인터 리시버로
구현한다면 결과는 어떻게 될까요?func (donald *DonaldDuck) quack() {
fmt.Println("Quack!")
}
# go-test/interface/slice_interface [go-test/interface/slice_interface.test]
./slice_interface_test.go:6:7: cannot use donaldDuck (type DonaldDuck) as type Duck in argument
to quack:
DonaldDuck does not implement Duck (quack method has pointer receiver)
FAIL go-test/interface/slice_interface [build failed]
자바스크립트로 직접 만들면서 배우는 - 자료구조와 알고리즘 강의 바로 가기
실습으로 마스터하는 OAuth 2.0: 기본부터 보안 위험까지 - OAuth 2.0 강의 바로 가기
기계인간 이종립, 소프트웨어 개발의 지혜 - Git 강의 바로 가기
코드숨에서 매주 스터디를 진행하고 있습니다. 메일을 등록하시면 새로운 스터디가 시작될 때 알려드릴게요!