2 回答
TA贡献1884条经验 获得超4个赞
Suits
并且Ranks
不是切片。它们是数组。数组是固定大小的类型,与切片不同。您不能将数组发送到需要切片的函数。因此,将它们声明为没有大小,它们将成为切片:
var Suits=[]string{...} var Ranks=[]string{...}
或者,如果要将它们保留为数组,则必须将切片传递给需要切片的函数:
indexOfSlice(str,Suits[:])
关于更好的方法的问题:您可以使用地图:
var Suits=map[string]int{"hearts":0, "spades":1, "diamonds":2, "clubs":3}
然后:
rankSuit=Suits[str]
TA贡献1798条经验 获得超7个赞
我会抽象你的类型,并为它们添加一些实用功能。
Card为,Suit和,创建自定义类型Rank允许您将比较和有效性函数附加到它们中的每一个。
如果您想要一个与ComparableJava 类似的界面,那么您也可以自己创建一个非常小的界面。为您的类型实现必要的功能以满足接口将很简单CompareTo,不过,我认为我提供的解决方案对类型的封装更好一些并且更容易测试。
我已经添加了在两张牌相等的情况下比较Suit的逻辑,但我不完全确定这背后的原因,因为通常打出相同等级的牌被认为是相等的牌。CardRank
祝你好运!
卡片/card.go
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
}
卡片/rank.go
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
}
卡/suit.go
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
}
main.go
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))
}
- 2 回答
- 0 关注
- 118 浏览
添加回答
举报