【问题标题】:How to create a literal slice of an alias to a builtin type in Go如何在 Go 中为内置类型创建别名的文字切片
【发布时间】:2013-08-06 07:47:46
【问题描述】:

我有一些操作接口类型切片的 golang 代码(可比较)。为了测试我的代码,我想创建一些假数据并对其进行操作。但是,我在以一种并不乏味的方式执行此操作时遇到了麻烦。我唯一能想到的就是创建一个满足 Comparable 接口的用于测试的新类型(在本例中为 int 类型的别名),然后为我的测试提供该类型的文字切片。我设想它看起来像下面这样:

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 类型的文字。其次,我必须编写大量这些函数。对我而言,使用字面量整数要方便得多。

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

此外,是否有更好的方法来完成我正在尝试做的事情,即生成满足用于测试的接口的硬数据?

【问题讨论】:

  • 你的代码看起来像 Java (Comparable, self)。为什么不直接使用 Java 而不是在 Go 中编写 Java?
  • @jnml 因为他在学习。教他围棋成语。

标签: go


【解决方案1】:
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)

【讨论】:

    【解决方案2】:

    有很多方法可以做到这一点。正如您正确指出的那样,问题是 Go 编译器无法自动将 int 转换为 Comparable (因为这样做需要找到所有可能的等效类型,并确定哪些等效类型满足 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
    }
    

    然后你只需要这样做:

    FunctionToTest(intToComparable([]int{ 7, 4, 2, 1 }))
    

    【讨论】:

      【解决方案3】:

      此外,是否有更好的方法来完成我正在尝试做的事情,即生成满足用于测试的接口的硬数据?

      也许吧。您遇到的问题是[]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})
             ....
      }
      

      (完全未经测试,仅用于说明的代码)

      【讨论】:

        猜你喜欢
        • 2018-10-27
        • 2013-11-03
        • 2015-09-15
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2021-03-03
        • 2020-02-04
        • 1970-01-01
        相关资源
        最近更新 更多