2012-11-22 4 views
3

입니다 INT64 :지도 [작업] 작업이 이제 내가 이동 라이브러리에 다음과 같은 인터페이스를 정의한다고 가정 해 봅시다 인터페이스

Register()에서
type Task interface { 
    Do() error 
} 

func Register(task Task) { ... } 

func GetId(task Task) int64 { ... } 

라이브러리 동료 각 작업 인스턴스가 고유 int64. GetId()은 주어진 작업에 대한 식별자를 반환해야합니다.

저의 초기 아이디어는 협회를 map[Task]int64으로 저장하는 것이 었습니다. 이것은 잘 작동하는 것처럼 보이지만, Task을 구현하는 객체가 동등 비교가 가능하지 않은 경우 (예 : map을 포함하는 struct) 파손될 것이라고 들었습니다. 나는 이것이 사실인지 여전히 점검 할 필요가있다.

대신에 struct { task Task; id int64 } 슬라이스를 사용하고 반복 해 보았습니다.하지만 여전히 동일한 평등이 필요합니다 (Task 인스턴스). 그리고 AFAIU는 Go에서 정체성 비교가 없습니다.

Task 인스턴스를 해당 ID로 어떻게 강하게 매핑 할 수 있습니까?

편집 : 두 솔루션 모두 지금까지 제안했지만 모든 태스크 구현에는 ID 처리를위한 반복적 인 코드가 포함되어야한다는 단점이 있습니다. 나는 그 코드를 임베디드 될 수있는 TaskBase struct에 제공 할 수 있지만 이상적으로는 ID에 대해 알고있는 구현을 필요로하지 않는 솔루션을 선호합니다 (라이브러리 내부에 있으며 의미가없는).

+0

더 간단한'map [int64] Task'를 사용하지 않는 이유는 무엇입니까? –

+0

주어진 작업의 ID를 찾고 싶습니다. 반대가 아닙니다. –

답변

4

더 완벽한 예 : 다니엘 제안

package main 

import (
    "fmt" 
    "math/rand" 
) 

type Task interface { 
    Do() error 
    ID() int64 
} 

type XTask struct { 
    id int64 
    // other stuff 
} 

func NewXTask(/*task parameters...*/) *XTask { 
    t := &XTask{ /*initialize members*/} 
    t.id = Register(t) 
    // possibly more initialization... 
    return t 
} 

func (t *XTask) Do() error { return nil } // stub 
func (t *XTask) ID() int64 { return t.id } 

var taskRegistry = map[int64]Task{} 

func Register(t Task) int64 { 
    var id int64 
    for { 
     id = rand.Int63() 
     if _, exists := taskRegistry[id]; !exists { 
      break 
     } 
    } 
    taskRegistry[id] = t 
    return id 
} 

func main() { 
    t1 := NewXTask() 
    t2 := NewXTask() 
    fmt.Printf("%x\n", t1.ID()) 
    fmt.Printf("%x\n", t2.ID()) 
} 

http://play.golang.org/p/1RzDiw7F9t이 나는 ​​ID 방법을 사용하고, 당신이 그것을 가지고 길에서 뒤로지도를 돌았 다. 이는 Task 객체가 자신의 ID를 알고 있기 때문에 Task에서 ID 로의 매핑이 필요하지 않기 때문입니다. 그러나 ID에서 타스크로의 맵핑은 고유성을 보장하는 데 유용합니다. 다른 ID로만 자신을 찾고 해당하는 Task 객체가 필요한 경우 다른 시간에 유용 할 수 있습니다.

또한이 예제는 goroutine-safe가 아닙니다. 필요한 경우 동기화를 추가해야합니다.

+0

그건 실제로 작동합니다, 감사합니다. 이 솔루션을 사용하려면 Task의 모든 구현에 ID를 처리하는 코드가 있어야합니다 (단 몇 줄이라도). –

+0

글쎄, http://play.golang.org/p/n8C1nz-SWN에서와 같이 퍼가기를 사용할 수 있지만 필자의 견해로는 코드의 복잡성이 조금 늘어나지 만, 몇 줄을 저장하면된다. – Sonia

+0

네, 저의 질문에 대한 편집에서 제안한 바입니다. 많은 Task 구현은 많은 사람들이 작성하므로 절약이 중요 할 수 있습니다. 나는 여전히 구현에서 코드가 필요없이 이것을 수행하는 방법을 찾고있다. –

관련 문제