duanmi4379 2015-05-30 21:41
浏览 54
已采纳

在Google App Engine for Go中,属性如何具有多个类型的值?

The Google App Engine for Go datastore docs say, " A property can have values of more than one type". There is no example or further explanation. (Version: appengine 1.9.19.)

How can a property have more than one type if you must declare that property with a specific type in the backing struct?

  • 写回答

1条回答 默认 最新

  • doucu9677 2015-05-31 10:23
    关注

    You do not necessarily have to declare a specific type for a property in a backing struct.

    By implementing the PropertyLoadSaver interface, you can dynamically do whatever you want with the properties of an entity during loading or before saving. See this answer which shows how to represent an entity as a general map[string]interface{} type in Go, so it can have dynamic properties.

    Back to your question:

    A property can have values of more than one type.

    This is true. But if you want to make this work, you will also have to utilize a custom loading/saving mechanism through the PropertyLoadSaver interface.

    First define a backing struct where the property which will have multiple values of different types may be an []interface{}:

    type MyMy struct {
        Objects []interface{}
    }
    

    Next we have to implement PropertyLoadSaver. When loading, we will just append all values to the Objects slice that come with the name "Objects".

    When saving, we will loop over the elements of the Objects slice and send all its values with the same property name. This will ensure they will be saved under the same property, and we also have to specify the Multiple field to be true (multi-value property):

    func (m *MyMy) Load(ch <-chan datastore.Property) error {
        for p := range ch { // Read until channel is closed
            if p.Name == "Objects" {
                m.Objects = append(m.Objects, p.Value)
            }
        }
        return nil
    }
    
    func (m *MyMy) Save(ch chan<- datastore.Property) error {
        defer close(ch)
        for _, v := range m.Objects {
            switch v2 := v.(type) {
            case int64: // Here v2 is of type int64
                ch <- datastore.Property{Name: "Objects", Value: v2, Multiple: true}
            case string:  // Here v2 is of type string
                ch <- datastore.Property{Name: "Objects", Value: v2, Multiple: true}
            case float64: // Here v2 is of type float64
                ch <- datastore.Property{Name: "Objects", Value: v2, Multiple: true}
            }
        }
        return nil
    }
    

    Note that setting a value of type interface{} as the Property.Value would result in an error, that is why I used a Type switch so I will set concrete types. In my example I only supported 3 types (int64, string and float64) but you can just as easily add more types by adding new case branches.

    And using it:

    And finally using our custom MyMy type to save a new entity with property "Objects" which will have multiple values and of different types:

    m := MyMy{[]interface{}{int64(1234), "strval", 32.2}}
    key, err := datastore.Put(c, datastore.NewIncompleteKey(c, "MyMy", nil), &m)
    
    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论

报告相同问题?

悬赏问题

  • ¥15 使用EMD去噪处理RML2016数据集时候的原理
  • ¥15 神经网络预测均方误差很小 但是图像上看着差别太大
  • ¥15 Oracle中如何从clob类型截取特定字符串后面的字符
  • ¥15 想通过pywinauto自动电机应用程序按钮,但是找不到应用程序按钮信息
  • ¥15 如何在炒股软件中,爬到我想看的日k线
  • ¥15 seatunnel 怎么配置Elasticsearch
  • ¥15 PSCAD安装问题 ERROR: Visual Studio 2013, 2015, 2017 or 2019 is not found in the system.
  • ¥15 (标签-MATLAB|关键词-多址)
  • ¥15 关于#MATLAB#的问题,如何解决?(相关搜索:信噪比,系统容量)
  • ¥500 52810做蓝牙接受端