Go언어 함수 매개변수 전달에서

조회수 696회
type Brand struct {
    Idx  string `json:"idx"`
    Code int    `json:"code"`
    Name string `json:"name"`
}
brands := make([]*Brand, 0)
r.DB.Raw(query).Scan(&brands)

위 와 같은 구조체를 가진 brands 변수에 DB 데이터를 넣어서
배열 형식의 구조체를 만들어 함수로 전달하고자 합니다.

func Test(brands interface{}){
  for i := range brands {
    fmt.Println(brands[i])
  }
}

여기서 직접 구조체를 명시해주는 방법도 있겠지만... 예시이며, 하고자 하는것은 어떤 타입의 구조체가 올지 모르는 상황이라
함수로 넘긴 배열형식의 구조체를 반복문을 사용하고 싶은데 brands가 interface 형식이라
반복문을 실행할 수 없네요...

func Test(brands []interface{}){
  for i := range brands {
    fmt.Println(brands[i])
  }
}

위 처럼 작성할 경우엔 매개변수 전달할때 에러가 나타납니다. Cannot use 'brands' (type []*model.Brand) as type []interface{}

3 답변

  • 좋아요

    0

    싫어요
    채택 취소하기
    package main
    
    import "fmt"
    
    func Test(brands []interface{}){
      for i := range brands {
        fmt.Println(brands[i])
      }
    }
    
    type Brand struct {
        Idx  string
        Code int
        Name string
    }
    
    func main() {
        parsed := []Brand{Brand{"1", 1, "one"}, Brand{"2", 2, "two"}}
        brands := make([]interface{}, len(parsed))
        for i, v := range parsed {
            brands[i] = v
        }
        Test(brands)
    }
    

    https://golang.org/doc/faq#convert_slice_of_interface https://stackoverflow.com/questions/27689058/convert-string-to-interface

    • 흐흠... 모르겠습니다. 이미 empty interface의 배열로 받기로 정해져 있다면 다이렉트로 넘기는 방식은 이게 최선이지 않을까 싶은데요. 개별적으로 메모리를 슬라이스 해야만 컴파일단계서 유추가 가능한 듯 보입니다. 아님 추상화 레벨을 한 단계 높인 상위 구조체 개념을 두어서... 만들면 될지는 모르겠지만 상세 구현이 어떻게 되는지 모르는 것이니.... (배보다 배꼽이 큰 상황이 될지도...) doodoji 2020.4.9 23:06
    • 감사합니다 덕분에 많은 도움이 되었습니다 강현우 2020.4.10 10:34
  • 크게 2가지 방법을 소개하겠습니다.

    1. Type Assertion

    func Test(brands interface{}) {
        brandsSlice, ok := brands.([]interface{})
        if !ok {
            // error
        }
        for i := range brandsSlice {
            fmt.Println(brandsSlice[i])
        }
    }
    

    이렇게 인자가 Slice인지 체크한 뒤 원하는 것을 하는 방법입니다.

    2. reflect

    func Test(brands interface{}) {
        switch reflect.TypeOf(brands).Kind() {
        case reflect.Slice:
            value := reflect.ValueOf(brands)
            for i := 0; i < value.Len(); i++ {
                fmt.Println(value.Index(i))
            }
        }
    }
    

    두번째 방법은 reflect를 쓰는 방법입니다. 이 방법은 reflect를 임포트 하셔야 합니다.

    • 1번 방법은 저도 스택오버플로우보고 해봤는데.. ok에서 false에 걸립니다. 강현우 2020.4.9 22:24
  • 여기 질문은어떻게남기나요?

    • (•́ ✖ •̀)
      알 수 없는 사용자

답변을 하려면 로그인이 필요합니다.

프로그래머스 커뮤니티는 개발자들을 위한 Q&A 서비스입니다. 로그인해야 답변을 작성하실 수 있습니다.

(ಠ_ಠ)
(ಠ‿ಠ)