2017-12-28 41 views
3

인수로 연기와 함께 사용할 수 있습니다. Playground.는 우리가 쉽게 <code>defer</code> 그것을 매개 변수로 함수를 전달하고 사용할 수 있습니다


그러나 우리가 방법를 통과하고 그 방법 recover를 호출해야하는 경우?

type MyStruct struct { 
    Data string 
} 

func main() { 
    a := &MyStruct{} 
    test(a.Recover) 
} 

func test(f func(int)) { 
    defer f(10) 
    panic("test") 
} 

func (m *MyStruct) Recover(arg int) { 
    e := recover() 
    fmt.Println(e) 
    fmt.Println(arg) 
} 

여기서 우리는 완전히 이해하지 못하는 이상한 행동을합니다. Playground.

메서드가 호출되는 것처럼 보이지만 recovernil을 반환하고 그 후에 (다른?) 패닉이 발생합니다. golang 문서 및 Google 검색 결과 중 어떤 것도 그러한 행동의 이유를 이해하는 데 도움이되지 않았습니다. 내가 뭘 놓치고 있니?

답변

3

recover() 기능 returns nil when not called directly from the deferred function.

method valuea.Recover을 통한 전화는 직접 호출이 아닙니다.

복구 호출하는 래퍼 함수와 방법을 사용

func main() { 
    a := &MyStruct{} 
    test(func(arg int) { a.Recover(arg, recover()) }) 
} 

func test(f func(int)) { 
    defer f(10) 
    panic("test") 
} 

func (m *MyStruct) Recover(arg int, e interface{}) { 
    fmt.Println(e) 
    fmt.Println(arg) 
} 

또 다른 옵션은 method expression을 사용하는 것입니다, 그러나 이것은 아마 당신이 달성하려고하는 것에서 벗어나고있다 :

func main() { 
    a := &MyStruct{} 
    test(a, (*MyStruct).Recover) 
} 

func test(a *MyStruct, f func(*MyStruct, int)) { 
    defer f(a, 10) 
    panic("test") 
} 

func (m *MyStruct) Recover(arg int) { 
    e := recover() 
    fmt.Println(e) 
    fmt.Println(arg) 
} 
+0

에게 그것을 문서에서 메서드 값을 통한 호출이 직접 호출이 아니라는 것을 분명히 알지 못했지만 지금은 알 수 있습니다. 설명해 주셔서 감사합니다! 전달 된 인수에서 메소드 값과 메소드 표현식을 구별 할 수있는 방법이 없다는 것을 정확하게 알고 있습니까? –

+0

메소드 값을 통한 호출이 직접 호출로 간주되지 않는 이유는 무엇입니까 (또는 누구라도) 알고 있습니까? –

+1

메소드 값에 대한 인수의 수는 기본 메소드에 대한 인수 수보다 1입니다. 메소드 값에 대한 호출이 메소드에 대한 직접 호출이 아니라는 사실이 뒤 따릅니다. 런타임에 함수가 주어지면 함수가 일반 함수, 함수 리터럴, 메소드 표현식 또는 메소드 값인지 여부를 판별 할 수 없습니다. –