1 Câu hỏi: Hàm Go chấp nhận tham số mảng khác nhau

câu hỏi được tạo ra tại Wed, May 8, 2019 12:00 AM

Tôi muốn sử dụng một hàm chung để sắp xếp các loại khác nhau:

type Foo struct {
  Name    string
  Another string
}

type Bar struct {
  Name  string
  Some  string
}

func unmarshal(data []byte, val *[]map[string]interface{}) {
  err := json.Unmarshal(data, val)

  if err != nil || (*val)[0]["Name"] == "" {
    *val = nil
  }
}

func main() {
  var foos []Foo
  var bars []Bar

  // fooData and barData are JSON strings retrieved from database
  unmarshal(fooData, &foos)
  unmarshal(barData, &bars)
}

Tôi gặp lỗi như cannot use &foo (type *[]Foo) as type *[]map[string]interface {} in argument to unmarshal.

Tôi đã thử sử dụng val interface{} làm tham số nhưng không hỗ trợ chỉ mục.

Làm thế nào tôi có thể đạt được mục tiêu sau đó? Cảm ơn.

    
- 5
  1. Trình biên dịch cho bạn biết rằng bạn đang chuyển một con trỏ tới một lát Foo , nhưng hàm này mong muốn một con trỏ tới một lát map[string]interface{} . Điều đó rõ ràng sẽ không hoạt động vì Foo không phải là bản đồ.
    2019-05-08 16: 11: 26Z
1 Câu trả lời                              1                         

Để làm việc với các loại lát tùy ý, hãy khai báo đối số là loại interface{} và sử dụng phản chiếu để truy cập giá trị:

func unmarshal(data []byte, v interface{}) {
    err := json.Unmarshal(data, v)
    rv := reflect.ValueOf(v).Elem()

    if err != nil || rv.Len() == 0 || rv.Index(0).FieldByName("Name").Interface() == "" {
        rv.Set(reflect.Zero(rv.Type()))
    }
}
    
2
2019-05-08 16: 45: 04Z
  1. Nó hoạt động! Cảm ơn. Một điều nữa, nếu tên trường không tồn tại, mã sẽ hoảng loạn trước panic: reflect: call of reflect.Value.Interface on zero Value. Làm cách nào tôi có thể thực hiện một số precheck để làm cho mã mạnh hơn?
    2019-05-09 01: 28: 14Z
  2. Kiểm tra giá trị được trả về từ FieldByNsme có hợp lệ không trước khi gọi Giao diện. godoc.org/reflect#Value.IsValid
    2019-05-09 01: 56: 24Z
nguồn đặt đây