如何在Go中为内置类型创建别名的文字切片

时间:2013-08-06 07:47:46

标签: go

我有一些Golang代码可以操作接口类型的切片(Comparable)。为了测试我的代码,我想创建一些假数据并对其进行操作。但是,我在以一种并非令人难以置信的单调乏味的方式进行此操作时遇到了麻烦。我唯一能想到的就是为测试创建一个新类型(在这种情况下是一个类型为int的别名),它满足Comparable接口,然后提供我那种类型的测试文字切片。我想它看起来像下面这样:

type Comparable interface {
    LT(Comparable) bool
    AsFloat() float64
} 

type testInt int 

func (self testInt) LT(other Comparable) bool { 
    return float64(self) < other.AsFloat() 
} 

func (self testInt) AsFloat() float64 { 
    return float64(self) 
} 

func TestAFunction(t *testing.T) { 
    FunctionToTest([]Comparable{7, 4, 2, 1})
    ....
}

但是,在这个例子中,编译器会抱怨int类型不能用作Comparable。我理解为什么这种情况正在发生,但我不确定如何解决它。首先,我不知道如何创建一个类型为testInt的文字。其次,我必须编写大量这些函数。使用文字整数对我的目的来说更方便。

有没有办法处理内置类型的类型别名,这样编译器可以用最少的代码正确地推断出正确的文字类型?

此外,是否有更好的方法可以完成我想要做的事情,即生成满足用于测试的接口的硬数据?

3 个答案:

答案 0 :(得分:4)

func NewWhatevers(a ...int) (r []Whatever) {
        r = make([]Whatever, len(a))
        for i, v := range a {
                r[i] = Whatever(v)
        }
        return
}

...

myWhatevers := NewWhatevers(7, 4, 2, 1)

答案 1 :(得分:2)

有很多方法可以实现这一目标。正如您所说的那样,问题在于Go编译器无法自动将int转换为Comparable(因为这样做需要找到所有可能的等效类型,并确定哪些等效类型满足{ {1}}界面,然后如果有多个...你明白了。因此,您必须做以下两件事之一:

编写显式类型转换:

Comparable

然而,如果你需要很多文字,这可能会非常烦人。因此,你也可以:

编写一个函数将FunctionToTest([]Comparable{ testInt(7), testInt(4), testInt(2), testInt(1) }) 转换为[]int

[]Comparable

然后你只需要这样做:

func intToComparable(i []int) []Comparable {
    c := make([]Comparable, len(i))
    for i, v := range i {
        c[i] = testInt(v)
    }
    return c
}

答案 2 :(得分:1)

  

此外,是否有更好的方法可以完成我想要做的事情,即生成满足用于测试的接口的硬数据?

也许。您遇到的问题是[]Comparable[]testInt根本不同,无法交换,因为内存中的底层表示不同。 如果您的代码不是关于Comparable的单个项目,而是关于可以比较的项目切片的更多信息,那么您可以重构代码以处理整个切片。

看一下package sort如何做到这一点:它不是在一片可比数据上运作,而是在“可比较的片段”上运作。

// FloatOrder is a slice with comparable and float-convertible elements 
type FloatOrder interface {
    Less(i, j int) bool  // Compare element i and j and return true first is less than the other
    Float(i int) float64 // Return element i as a float64
}

type testInts []int
func (n testInts) Less(i, j int) bool {return n[i] < n[j]}
func (n testInts) Float(i int) float64 { return float64(n[i]) }

func FunctionTotest(fo FloatOrder) { ... }

func TestAFunction(t *testing.T) { 
       FunctionToTest(testInts{1,2,3,4})
       ....
}

(完全未经测试的插图代码)