【问题标题】:Append Slice to Struct in Golang在 Golang 中将切片附加到结构
【发布时间】:2018-07-20 17:33:37
【问题描述】:

我正在尝试将一个数组附加到另​​一个数组(或切片到结构?) 一个查询(目标)的结果会被迭代并附加另一个查询的结果(每个检查点的目标),基于之前的查询结果。id

然后在模板中迭代结果。

型号

type Target struct {
    ID              uint32        `db:"id"`
    CriteriaID      string        `db:"criteria_id"`
    TargetCheck     []*TargetCheck
}

type TargetCheck struct {
    ID              uint32        `db:"id"` 
    TargetID        string        `db:"target_id"`
    CheckpointID    template.HTML `db:"checkpoint_id"`
    Name            string        `db:"name"`
}

func TargetByCriteriaID(criteriaID string) ([]Target, error) {
... <return rows> 
}

func CheckpointByTargetID(targetID uint32) ([]TargetCheck, error) {
... <return rows>
}

func (target *Target) AddItem(TargetCheckItem *TargetCheck) []*TargetCheck {
    target.TargetCheck = append(target.TargetCheck, TargetCheckItem)
    return target.TargetCheck
}

控制器

func CriteriaBrowseGET(w http.ResponseWriter, r *http.Request) {

criteriaID := 5
target, err := model.TargetByCriteriaID(criteriaID)
for i := range target {
        targetCheck, err := model.CheckpointByTargetID(target[i].ID)
        target = model.Target.AddItem(targetCheck)
    }

v := view.New(r)
v.Name = "criteria/browse"
v.Vars["target"] = target
v.Render(w)

}

查看

{{range $index, $content := .target}}
    <p>Target: {{.ID}}</p>
                    {{if .}}
                        {{range .TargetCheck}}
                            <p>{{.CheckpointID}}</p>
                            <p>{{.Name}}</p>
                        {{end}}
                    {{end}}

{{end}}

在执行go build 时会说:

vendor\app\controller\criteria.go:74:24: 无效的方法表达式 model.Target.AddItem(需要指针接收器:(*model.Target).AddItem)

vendor\app\controller\criteria.go:74:24: model.Target.AddItem 未定义(model.Target 类型没有 AddItem 方法)

上面的代码有问题吗?

【问题讨论】:

    标签: go


    【解决方案1】:

    target = model.Target.AddItem(targetCheck) 错误,您应该调用从 range 语句中获得的 target 值的方法,因此请改为使用 &amp;target.AddItem(targetCheck)

    【讨论】:

      【解决方案2】:

      错误清楚地表明:

      vendor\app\controller\criteria.go:74:24: 无效的方法表达式 model.Target.AddItem(需要指针接收器:(*model.Target).AddItem)

      vendor\app\controller\criteria.go:74:24: model.Target.AddItem 未定义(model.Target 类型没有 AddItem 方法)

      你有指向方法AddItem的指针接收器:

      func (target *Target) AddItem(TargetCheckItem *TargetCheck) []*TargetCheck {
          target.TargetCheck = append(target.TargetCheck, TargetCheckItem)
          return target.TargetCheck
      }
      

      但是当您从控制器调用函数时,您正在使用值接收器:

          targetCheck, err := model.CheckpointByTargetID(target[i].ID)
          target = model.Target.AddItem(targetCheck)
      

      在调用AddItem函数时应该传递指针接收器。

      Playground Example

      Golang 规范中描述了 Method Declaration:

      接收者是通过前面的额外参数部分指定的 方法名称。该参数部分必须声明一个非可变参数 参数,接收器。它的类型必须是 T 或 *T 的形式 (可能使用括号)其中 T 是类型名称。表示的类型 由 T 称为接收器基类型;它不能是指针或 接口类型,并且它必须与 方法。该方法被称为绑定到基类型和方法 name 仅在 T 或 *T 类型的选择器中可见。

      给定类型 Point,声明:

      func (p *Point) Length() float64 { 返回数学.Sqrt(p.x * p.x + p.y * p.y) }

      func (p *Point) Scale(factor float64) {
          p.x *= factor
          p.y *= factor
      }
      

      将接收器类型 *Point 的 Length 和 Scale 方法绑定到 基本类型 Point。

      【讨论】:

        猜你喜欢
        • 2016-12-24
        • 2013-12-10
        • 2018-12-05
        • 1970-01-01
        • 2019-04-12
        • 2016-05-25
        • 2019-01-02
        • 1970-01-01
        • 2021-07-03
        相关资源
        最近更新 更多