GoLang의 인터페이스, 포인터 등
9072 단어 GO
우선, 나는 세 개의 인터페이스, 하나의 구조와 세 가지 방법을 정했다.
type DeptModeFull interface {
Name() string
SetName(name string)
Relocate(building string, floor uint8)
}
type DeptModeA interface {
Name() string
SetName(name string)
}
type DeptModeB interface {
Relocate(building string, floor uint8)
}
type Dept struct {
name string
building string
floor uint8
Key string
}
func (self Dept) Name() string {
return self.name
}
func (self Dept) SetName(name string) {
self.name = name
}
func (self *Dept) Relocate(building string, floor uint8) {
self.building = building
self.floor = floor
}
그 후에 나는 몇 가지 테스트 코드를 썼다.
dept1 :=
Dept{
name: "MySohu",
building: "Internet",
floor: 7}
switch v := interface{}(dept1).(type) {
case DeptModeFull:
fmt.Printf("The dept1 is a DeptModeFull.
")
case DeptModeB:
fmt.Printf("The dept1 is a DeptModeB.
")
case DeptModeA:
fmt.Printf("The dept1 is a DeptModeA.
")
default:
fmt.Printf("The type of dept1 is %v
", v)
}
deptPtr1 := &dept1
if _, ok := interface{}(deptPtr1).(DeptModeFull); ok {
fmt.Printf("The deptPtr1 is a DeptModeFull.
")
}
if _, ok := interface{}(deptPtr1).(DeptModeA); ok {
fmt.Printf("The deptPtr1 is a DeptModeA.
")
}
if _, ok := interface{}(deptPtr1).(DeptModeB); ok {
fmt.Printf("The deptPtr1 is a DeptModeB.
")
}
인쇄된 내용:
The dept1 is a DeptModeA.
The deptPtr1 is a DeptModeFull.
The deptPtr1 is a DeptModeA.
The deptPtr1 is a DeptModeB.
내 질문:
왜 Dept의 실례의 바늘은 모든 세 인터페이스의 실현으로 판정되고 Dept의 실례는 DeptModeA 인터페이스의 실현일 뿐입니까?
어느 큰 소가 말씀해 주시겠어요?
대답 1:
T가 struct라고 가정하면 Go에서는 다음과 같은 몇 가지 원칙을 따릅니다.
따라서 위의 예는 dept1이 가지고 있는 방법일 것입니다: Name과 SetName
&dept1에는 Name, SetName 및 Relocate가 있습니다.
이게 바로 Go 안에서 디자인 방법을 쓸 때 Receiver의 장르에 신경을 써야 돼요.
대답 2:
이상의 고수들의 해답에 감사드리며 공식 규범 문서를 자세히 봤습니다(http://tip.golang.org/ref/spec의 관련 내용은 위의 예에 대해 제가 다시 한 번 요약해 보겠습니다(위의 몇 분이 제공한 답안이 포함되어 있습니다).
1. 구조
Dept
의 방법은 방법 수신자가 Dept인 방법만 포함한다. 즉, Name()
과 SetName()
).따라서 구조 Dept의 실례는 DeptModeA
의 실현에 불과하다.2. 구조의 지침 *Dept
의 방법집은 방법 수용자가 Dept
과 *Dept
인 방법, 즉 Name()
, SetName()
과 Relocate()
을 포함한다.따라서 인터페이스 Dept의 실례적인 지침은 모든 세 개의 인터페이스인 DeptModeFull
, DeptModeA
과 DeptModeB
의 실현이다.그러나 나는 상술한 디자인과 원칙이 방법이 호출한 디자인과 약간 일치하지 않는다고 생각한다. 아래의 코드를 보십시오.
dept1.Relocate("Media", 12)
fmt.Printf("Dept: %v
", dept1)
fmt.Printf("Dept name: %v
", deptPtr1.Name())
인쇄된 내용:
Dept: {MySohu Media 12 }
Dept name: MySohu
구조
Dept
의 실례는 지침 방법을 집중적으로 사용할 수 있다는 뜻이다.설계가 일치하지 않는 점은 구조의 방문법집은 수신자가 지침을 주는 방법을 포함하지 않는 이상 왜 구조의 실례에서 지침을 사용하는 방법을 사용할 수 있겠는가?반대로 보면 구조의 실례가 그 인터페이스 방문법집의 방법을 사용할 수 있는 이상 왜 구조의 방법집에 이러한 방법을 직접 포함하지 못하게 합니까?
그러나 어쨌든 이것은 제3조 규칙(공식규범의 의역)을 인용했다. 3. 구조의 실례인
x
이'어디서 찾을 수 있는'것이고 &x
의 방법은 방법 m
을 집중적으로 포함하면 x.m()
은 (&x).m()
의 속기(단축방식)이다.그래서 사실
dept1.Relocate("Media", 12)
자동으로 바뀌었어?
(&dept1).Relocate("Media", 12)
공부했어.
주소를 찾는다는 뜻은 아마도 이미 실례가 된 것일 것이다.하면, 만약, 만약...
var deptPtr2 *Dept
deptPtr2.Relocate("Media", 12)
안돼.반대로:
var deptPtr2 Dept
deptPtr2.Relocate("Media", 12)
할 수 있어.차이는 바로 여기에 있다.
========================================================================
별례
type Reader interface {read ()} type Writer interface {write ()}//상기 두 인터페이스의 구현 클래스 type My ReadWrite struct {}func (mrw * My ReadWrite) read () read () {fmt. Pritln ("My ReadWrite...read))}func (mrw * My ReadWrite) write ()상기 두 인터페이스 type ReadWriter interface {Reader Writer}//위의 인터페이스는 type ReadWriter V2 interface {read () write ()}//ReadWriter와 ReadWriter V2 두 인터페이스가 같은 값이므로 func interfaceTest0104 () {mrw: = My ReadWrite {mrw.read() mrw.write()//mrw 객체는read() 방법과 write() 방법을 구현하므로 ReadWriter 및 ReadWriter V2 var rw1 ReadWriter = mrw rw1.read() rw1.write() fmt.Println("------") var rw2 ReadWriterV2 = mrw rw2.read() rw2.write ()//동시에 ReadWriter와 ReadWriter V2 두 인터페이스 대상은 서로 rw1 = rw2 rw2 = rw2 = rw1}func main () {interfaceTest0104 ()}
빨간색으로 표시된 두 줄은 오류를 보고할 수 있다
main\interface.go:43:6: cannot use mrw (type MyReadWrite) as type ReadWriter in assignment: MyReadWrite does not implement ReadWriter (read method has pointer receiver)main\interface.go:48:6: cannot use mrw (type MyReadWrite) as type ReadWriterV2 in assignment: MyReadWrite does not implement ReadWriterV2 (read method has pointer receiver)
ReadWriter와 ReadWriter V2의 실현은 모두 수락된 포인터 파라미터이기 때문에 *T receiver이고 mrw는 T receiver만 있고 파라미터를 포인터로 실현하는 방법이 없기 때문에 (이곳의 mrw는 어떤 방법도 실현하지 못했을 수 있습니다. mrw.read()가 성공할 수 있는 것은 위에서 언급한 세 번째 점 때문) 값을 부여할 수 없습니다.
mrw:=&MyReadWrite {}로 변경하면 오류 없음
이 내용에 흥미가 있습니까?
현재 기사가 여러분의 문제를 해결하지 못하는 경우 AI 엔진은 머신러닝 분석(스마트 모델이 방금 만들어져 부정확한 경우가 있을 수 있음)을 통해 가장 유사한 기사를 추천합니다:
Go 사진 저장텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
CC BY-SA 2.5, CC BY-SA 3.0 및 CC BY-SA 4.0에 따라 라이센스가 부여됩니다.