Go 比较两个结构是否大于

Go 比较两个结构是否大于,go,Go,我试图比较两个扑克牌结构,看看哪张扑克牌比另一张更好。我能在网上找到的所有关于比较围棋结构的东西都是为了平等而比较,但在这种情况下,我想说的是黑桃a比梅花7更有价值 考虑到Go没有提供Java的comparator接口之类的现成功能,我想创建自己的函数来使用循环进行卡片比较,但我收到了错误消息: # cards/card card/Card.go:12:19: cannot use Ranks (type [13]string) as type []string in argument to i

我试图比较两个扑克牌结构,看看哪张扑克牌比另一张更好。我能在网上找到的所有关于比较围棋结构的东西都是为了平等而比较,但在这种情况下,我想说的是黑桃a比梅花7更有价值

考虑到Go没有提供Java的comparator接口之类的现成功能,我想创建自己的函数来使用循环进行卡片比较,但我收到了错误消息:

# cards/card
card/Card.go:12:19: cannot use Ranks (type [13]string) as type []string in argument to indexOfSlice
card/Card.go:14:26: cannot use Ranks (type [13]string) as type []string in argument to indexOfSlice
card/Card.go:15:20: cannot use Suits (type [4]string) as type []string in argument to indexOfSlice
这是我的卡片套装:

package Card

var Suits = [4]string {"hearts", "spades", "diamonds", "clubs"}
var Ranks = [13]string {"2", "3", "4", "5", "6", "7", "8", "9", "10", "jack", "queen", "king", "ace"}

type Card struct {
        Value string
        Suit string
}

// if the index in the slices is greater for a than for b, then a must be greater value
func CardIsGreater(a Card, b Card) bool {
        if indexOfSlice(a.Value, Ranks) > indexOfSlice(b.Value, Ranks) {
                return true;
        } else if indexOfSlice(a.Value, Ranks) == indexOfSlice(b.Value, Ranks) {
                if indexOfSlice(a.Suit, Suits) > indexOfSlice(b.Suit, Suits) {
                        return true;
                }
        } else {
                return false;
        }
        // lets ignore for a second that invalid ranks or suits will break this comparator
        return false;
}

// finds the index of a suit or value in a slice
func indexOfSlice(element string, slice []string) int {
        for i, _ := range slice {
                if slice[i] == element {
                        return i;
                }
        }
        return -1;
}
这是我的主要套餐:

package main

import (
    "fmt"
    "cards/card"
)

func main () {
    card := Card.Card{Suit: "hearts", Value: "ace"}
    card2 := Card.Card{Suit: "diamonds", Value: "queen"}
    fmt.Println(card)
    fmt.Println(card2)
    fmt.Println(Card.CardIsGreater(card, card2)
}
在这种情况下,我如何让indexOfSlice助手函数接受字符串片段作为其参数之一?如果我从谷歌搜索首页随机阅读了一篇教程,它看起来应该可以工作:

这个堆栈溢出回答解释了Go基本上是强制执行类型安全性,因为类型[]字符串可以通过许多方式得到满足:。如果是这样的话,那么我该如何回避这个问题呢

此外,这是比较结构的正确方法吗?如果将空格王牌与心形王牌进行比较,则在西装和等级片上需要4圈!!为了真正得到比较。

西装和军衔不是切片。它们是数组。数组是固定大小的类型,它不同于切片。不能将数组发送到需要切片的函数。因此,声明它们时不带大小,它们将成为切片:

var Suits=[]string{...}
var Ranks=[]string{...}
或者,如果要将它们保留为数组,则必须将切片传递给需要切片的函数:

indexOfSlice(str,Suits[:])
关于如何更好地执行此操作的问题:您可以使用地图:

var Suits=map[string]int{"hearts":0, "spades":1, "diamonds":2, "clubs":3}
然后:


我将抽象您的类型,并向它们添加一些实用函数

为卡片、套装和等级创建自定义类型,允许您将比较和有效性函数附加到每个类型

如果您想要一个类似于Java中Comparable的接口,那么您也可以自己创建一个非常小的接口。为您的类型实现必要的CompareTo函数以满足接口要求是非常简单的,不过,我认为我提供的解决方案封装类型更好,更容易测试

我添加了逻辑来比较两张牌的等级相等的情况下的牌套,但我不完全确定这背后的原因,因为通常情况下,等级相等的牌被认为是相等的牌

祝你好运

卡片

卡片/套装


请减少您的代码,以便您有一个感谢。在这种情况下,我混淆了数组和切片。谢谢你的评论。在一张地图上有人建议。比较映射的值要比实现这些接口快得多。但我很好奇,为什么要创建一个名为sentinel的套装?在Go中,当我像这里一样创建枚举时,我总是创建一个sentinel值rhat保留列表中的最后一个值,以便检查验证。请参阅有效函数。只要sentinel始终是最后一个,我就可以轻松检查枚举是否有效:
rankSuit=Suits[str]
func New(s Suit, r Rank) (*Card, error) {
    if !s.Valid() {
        return nil, errors.New("invalid suit")
    }

    if !r.Valid() {
        return nil, errors.New("invalid rank")
    }

    return &Card{suit: s, rank: r}, nil
}

type Card struct {
    suit Suit
    rank Rank
}

func (c *Card) Cmp(c2 *Card) int {
    rankCmp := c.rank.Cmp(c2.rank)
    if rankCmp != 0 {
        return rankCmp
    }

    if c.suit < c2.suit {
        return -1
    }

    if c.suit > c2.suit {
        return 1
    }

    return 0
}
type Rank string

var ranks = []Rank{"2", "3", "4", "5", "6", "7", "8", "9", "10", "J", "Q", "K", "A"}

func (r Rank) Cmp(r2 Rank) int {
    for _, rank := range ranks {
        if rank == r {
            return -1
        }

        if rank == r2 {
            return 1
        }
    }

    return 0
}

func (r Rank) Valid() bool {
    for _, rank := range ranks {
        if r == rank {
            return true
        }
    }

    return false
}
type Suit int

const (
    unknown  Suit = 1
    Hearts   Suit = 2
    Spades   Suit = 3
    Diamonds Suit = 4
    Clubs    Suit = 5
    sentinel Suit = 6
)

func (s Suit) Valid() bool {
    return s > unknown && s < sentinel
}
func main() {
    c1, err := cards.New(Hearts, "2")
    if err != nil {
        fmt.Println(err)
        return
    }

    c2, err := New(cards.Diamonds, "A")
    if err != nil {
        fmt.Println(err)
        return
    }

    c3, err := New(cards.Spades, "A")
    if err != nil {
        fmt.Println(err)
        return
    }

    fmt.Printf("c1 - c2: %d\n", c1.Cmp(c2))
    fmt.Printf("c2 - c3: %d\n", c2.Cmp(c3))
    fmt.Printf("c1 - c3: %d\n", c1.Cmp(c3))
}