2017-12-13 1 views
-2

방금 ​​Go 언어를 배우기 시작했고 슬라이스에서 임의의 서브 시퀀스를 선택할 함수를 작성하려고합니다. 그러나이 슬라이스에 저장할 수있는 값의 유형을 알 수는 없으며 정수, 문자열 또는 일부 구조체의 요소가 될 수 있습니다. 예를 들어, 가정하자 나는 구조가 다음과 같이입력 슬라이스 인수에 따라 다른 연산을 수행하는 함수 작성

이제
type person struct { 
    name string 
    age int 
} 

type animal struct { 
    name string 
    age int 
    breed string 
} 

, 나는 기능 getRandomSequence를 구축하고자 : 슬라이스 S와 기능 l로부터 무작위로 선택된 요소를 포함하는 슬라이스를 반환하는 길이 (L) 인수로 주어진 내가 겪은 문제는 - 가능한 모든 슬라이스에 대해이 기능을 작동시키는 방법이었습니다. 나는 다음을 시도했다 :

func GetRandomSequence(S interface{}, l int) []interface{} { 
    switch S.(type) { 
    case person: 
     // Do random selection of l elements from S and return them 
    case animal: 
     // Do random selection of l elements from S and return them 
    case int: 
    // Do random selection of l elements from S and return them 
    } 
    return " Not Recognised" 
} 

누군가가 그런 기능을 어떻게 쓸 수 있는지 제안 할 수 있습니까? S가 어떤 유형의 단일 요소가 되더라도 (즉, []interface{} 대신 interface{} 일 것입니다.) 비슷한 문제 (즉, 일반 기능)를 수행 할 수 있지만이 문제를 해결하는 방법을 찾을 수는 없습니다.

+1

질문 본문에 암시되어있는 것과 같이 다른 슬라이스 유형에서 동일한 작업을 수행하는 방법을 묻거나 제목에 무엇을 말하고 있습니까? –

+1

당신이 처음이라면 최고의 조언은 언어에 맞서 싸우지 않고 그런 기능을 쓰지 않는 것입니다. 둘 또는 셋. – Volker

답변

1

그냥 interface{}이 아닌 []interface{}을 사용하십시오. 빈 인터페이스는 슬라이스를 포함하여 모든 유형을 저장할 수 있습니다. (내가 테스트하지 않았더라도)

코드를 다음과 같이 보일 것입니다 :

func GetRandomSequence(S interface{}, l int) interface{} { 
    returnSlice := []interface{} 
    switch v := s.(type) { 
    // inside the switch v has the value of S converted to the type 
    case []person: 
     // v is a slice of persons here 
    case []animal: 
     // v is a slice of animals here 
    case []int: 
     // v is a slice of ints here 
    case default: 
     // v is of type interface{} because i didn't match any type on the switch 
     // I recommend you return nil on error instead of a string 
     // or always return 2 things, the value and an error like 
     // the standard library 
     return "Not Recognized" 
    } 
    rerurn returnSlice 
} 

난 당신이 완전한 Tour of go을하지만,이 질문에 대한 대답은 here입니다 좋습니다.

정확히 원하는대로 슬라이스 유형이 다르지만 슬라이스가 interface{} 인 것처럼 보입니다. 함수에 당신이 요소의 형태에 대해 걱정하지 않는다 슬라이스에서 임의의 요소를 추출하는 경우 만 수행

func GetRandomSequence(S []interface{}, l int) []interface{} { 
    returnSlice := make([]interface{}, 0, l) 
    for i:=0; i<l; i++ { 
     // S[i] here is always of type interface{} 
     returnSlice = append(returnSlice, S[getRnd()]) // you need to implement getRnd() or just "math/rand" or something. 
    } 
    return returnSlice 
} 
1

슬라이스 지수와 함께 작동하는 예제 함수를 작성합니다.

// Sample k random elements from set of n elements. 
// The function set sets an element in the output given 
// an index in the output and the index in the input. 
func sample(k int, n int, assign func(out int, in int)) { 
    for i := 0; i < k; i++ { 
     set(i, i) 
    } 
    for i := k; i < n; i++ { 
     j := rand.Intn(i + 1) 
     if j < k { 
      set(j, i) 
     } 
    } 
} 

이처럼 사용 만이 모든 유형의 슬라이스에 사용할 수있는 길이 인덱스 값

in := []person{ {"John", 10}, {"Sally", 11}, {"James", 9}, {"Eve", 8} } 
out := make([]person, 2) 
sample(len(out), len(in), func(i, j int) { out[i] = in[j] }) 

sample 때문에 작품.

이 접근법은 표준 라이브러리의 sort.Search과 비슷합니다.

+0

주변의 영리한 작업 –

관련 문제