【问题标题】:In Go, when using multiple return statements, how do you invoke each specific one?在 Go 中,当使用多个 return 语句时,如何调用每个特定的语句?
【发布时间】:2014-03-15 12:26:57
【问题描述】:

我正在尝试使用排序方法的两种变体:一种按名称对元素进行排序,另一种按薪水对元素进行排序。当我的 less 方法比较whatever.salary 时,sort.Sort(people(data)) 有效。如果我将其更改为whatever.name,它也可以工作。我希望能够在 less 方法中专门调用这两个选项,如下面的代码所示。我的逻辑是使用 sort.Sort(people(data.name)) 作为姓名,使用 sort.Sort(people(data.salary)) 作为薪水。这些都不起作用。这也能做到吗?

package main

import (
    "fmt"
    "sort"
)

type Comparable interface {
    Len()
    Less(i, j int) bool
    Swap(i, j int)
}

type person struct {
    name   string
    salary float64
}

func (a person) String() string {
    return fmt.Sprintf("%s: %g \n", a.name, a.salary)
}

type people []*person

func (a people) Len() int {
    return len(a)
}
func (a people) Less(i, j int) bool {
    return a[i].salary < a[j].salary
    return a[i].name < a[j].name
}
func (a people) Swap(i, j int) {
    a[i], a[j] = a[j], a[i]
}

func main() {

    var data = make(people, 10)

    var a, b, c, d, e, f, g, h, i, j person

    a.name, b.name, c.name, d.name, e.name, f.name,
        g.name, h.name, i.name, j.name = "Sheila Broflovski", "Ben Affleck",
        "Mr. Hankey", "Stan Marsh", "Kyle Broflovski", "Eric Cartman",
        "Kenny McCormick", "Mr. Garrison", "Matt Stone", "Trey Parker"

    a.salary, b.salary, c.salary, d.salary, e.salary, f.salary,
        g.salary, h.salary, i.salary, j.salary = 82000, 74000, 0, 400,
        2500, 1000, 4, 34000, 234000, 234000
    a.salary = 82000

    data[0] = &a
    data[1] = &b
    data[2] = &c
    data[3] = &d
    data[4] = &e
    data[5] = &f
    data[6] = &g
    data[7] = &h
    data[8] = &i
    data[9] = &j

    fmt.Println("\n\n\n")
    fmt.Print(data)
    sort.Sort(people(data))        //This works even with the two return statements
    sort.Sort(people(data.name))   //This does not work. Exist, a version that does?
    sort.Sort(people(data.salary)) //This does not work. Exist, a version that does?
    fmt.Println("\n\n\n")
    fmt.Print(data)
}

【问题讨论】:

    标签: sorting types interface go return-value


    【解决方案1】:

    要使用标准库sort 包实现第二次排序,您需要定义一个实现sort.Interface 的辅助类型。要处理示例中的工资案例,您可以执行以下操作:

    type bySalary struct {
        people
    }
    
    func (s bySalary) Less(i, j int) bool {
        return s.people[i].salary < s.people[j].salary
    }
    

    这里,sort.Interface 所需的LenSwap 方法来自嵌入的people 切片,而我提供了替换比较操作。要对people 数组进行排序,您现在可以调用:

    sort.Sort(bySalary{data})
    

    使用此模式,您可以轻松实现所需的任意数量的附加排序键,并且重复代码非常少。

    你可以在这里玩这个例子:http://play.golang.org/p/kq3SuXMylT

    【讨论】:

      【解决方案2】:

      介绍排序方法的常用方法是使用描述排序条件的新类型。这里是byNamebySalary。然后你可以使用sort.Sort(byName(data))进行排序。

      这里有一些演示代码。 Go 在构建数据结构方面也非常有用(例如,在表驱动测试中大量使用),这也可以帮助在这里构建您的人员数据。

      package main
      
      import "fmt"
      import "sort"
      
      type person struct {
          Name   string
          Salary float64
      }
      
      type people []*person
      
      type byName people
      type bySalary people
      
      func (p byName) Len() int           { return len(p) }
      func (p byName) Less(i, j int) bool { return p[i].Name < p[j].Name }
      func (p byName) Swap(i, j int)      { p[i], p[j] = p[j], p[i] }
      
      func (p bySalary) Len() int           { return len(p) }
      func (p bySalary) Less(i, j int) bool { return p[i].Salary < p[j].Salary }
      func (p bySalary) Swap(i, j int)      { p[i], p[j] = p[j], p[i] }
      
      func main() {
          p := people{
              {"Sheila Broflovski", 82000},
              {"Ben Affleck", 74000},
              {"Mr. Hankey", 0},
              {"Stan Marsh", 400},
              {"Kyle Broflovski", 2500},
              {"Eric Cartman", 1000},
              {"Kenny McCormick", 4},
              {"Mr. Garrison", 34000},
              {"Matt Stone", 234000},
              {"Trey Parker", 234000},
          }
          fmt.Println("by name")
          sort.Sort(byName(p))
          for _, x := range p {
              fmt.Println(*x)
          }
          fmt.Println("by salary")
          sort.Sort(bySalary(p))
          for _, x := range p {
              fmt.Println(*x)
          }
      }
      

      【讨论】:

        猜你喜欢
        • 2013-03-02
        • 1970-01-01
        • 1970-01-01
        • 2020-06-23
        • 1970-01-01
        • 2021-07-06
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多