2015-01-27 2 views
5

범위를 표현하는 관용적 방법이 있다면의 의미가 있는지 궁금합니다. 범위까지 내가 좋아하는 일을 의미 :golang에 관용 영역 유효성 검사가 있습니까?

  • 이 (oneliner 대신 명시 적으로 잠금 + DEFFERED 잠금 해제의),
  • 로깅 기능 (또는 코드 블록) 입구와 출구,
  • 측정 실행 시간 뮤텍스를 범위. 처음 두 개의 글 머리 기호에 대한

예제 코드 :

package main 

import "log" 
import "sync" 

func Scoped(m *sync.Mutex) func() { 
    m.Lock() 
    return func() { 
     m.Unlock() 
    } 
} 

func Log(what string) func() { 
    log.Println(what, "started") 
    return func() { 
     log.Println(what, "done") 
    } 
} 

func main() { 
    defer Log("testing")() 

    m := &sync.Mutex{} // obviously mutex should be from other source in real life 
    defer Scoped(m)() 
    // use m 
} 

https://play.golang.org/p/33j-GrBWSq

은 기본적으로 우리는 하나 개의 함수 호출 지금 (예 : 뮤텍스 잠금) 할 필요가 있고, 하나의 전화가 연기한다 지연 (예 : 뮤텍스 잠금 해제). 여기에 이름없는 함수를 반환하는 방법을 제안했지만 쉽게 이름을 지정할 수 있습니다 (함수 필드가있는 구조체 반환).

한 가지 문제가 있습니다. 사용자는 첫 번째 통화 결과를 '잊어 버릴'수 있습니다.

이 코드는 관용적 일 수 있습니까?

+0

."관용적 인"방법은 명시 적으로'lock()'과'defer unlock()'을 호출하는 것입니다. –

+0

이 접근법은 [Effective Go trace example] (https://golang.org/doc/effective_go.html##)에서 사용됩니다. 연기). –

답변

4

저는 이것을하기위한 관용적 인 방법이 있다고 생각하지 않습니다. 왜 그렇게하고 싶지 않은지 잘 모르겠다. 정말 쓸만하지 않은가?

m.Lock() 
defer m.Unlock() 

?

+2

이것은 참으로 관용적 인 방법입니다. (신이 나는이 모든 관용적 인 말도 안되는 것을 싫어하기 시작합니다.) 그러나 OP가 제안한 패턴은 오히려 멋진 IMO입니다. –

+0

'로깅 엔진'은 한 줄만 입력해야하는 경우에 가장 적합합니다. 사용자가 일부 작은 기능을 로깅하지 않을 가능성이 커지고 있습니다. – Kokos

+0

우리의 예제 로거에서 잘못된 변수 (_j_ 대신 _i_)를 사용하거나 다른 문자열을 입력 할 수도 있습니다 (로그 분석 도구에서 혼란을 야기 할 수 있음). – Kokos

3

제안 된 솔루션은 이미 훌륭합니다. defer 끝에 전화해야하는 func 유형의 값을 반환합니다.

당신은 (A func 값을 반환)이를 방지하지만,이 함수 호출의 시작 이벤트와 이벤트를 기록 또 다른 하나를 기록 일이있을 수 있습니다.

대안은 defer 문으로 계산 된 지연된 (함수 대신) 지연된 함수의 매개 변수 값을 생성하는 함수 호출을 작성하는 것이며,이 방법으로도 여전히 한 행으로 남아 있습니다.

또한 Go Playground에 그것을 시도 할 수 있습니다 :

func start(s string) string { 
    fmt.Println("Started", s) 
    return s 
} 

func end(name string) { 
    fmt.Println("Ended", name) 
} 

func main() { 
    defer end(start("main")) 

    fmt.Println("Doing main's work...") 
} 

출력 :

Started main 
Doing main's work... 
Ended main 
0

내가 질문 idiomaticity 이동과 관련이없는 생각이 때 기능 코드에 대해 추론하기 위하여 일반적으로 더 나은 것 같다 어느 쪽이라도 동일하게 행동하십시오. 상태를 유지하려면 개체를 만들고 그 개체의 메서드로 함수를 정의하는 것이 좋습니다.

type message string 
func (foo message) Log(bar string){ 
    if bar==nil{doSomethingSpecial()} 
    switch foo{ 
     case something: doSomething() 
     ... 
     case nil: doSomethingInitial() 
     default: doDefault() 
    } 
    log.Println(bar, "started") 
    foo=bar 
} 
1

같은이 범위으로 익명 함수를 타고 의미 : 나는 그것을 할 수있는 짧은 방법을 생각할 수 없다

func() { 
    Entrance() 
    defer Exit() 
    // anything you want to do in this scope 
}() 
관련 문제