2016-08-03 76 views
0

我想为任何实现Distance()方法的坐标类型事物定义接口,该方法可用于计算距离(可能是笛卡尔,也许是按时间顺序等)坐标型相同类型的东西。请参阅Golang接口方法中的实现类型

这是总体思路:

type Distancer interface { 
     Distance(other interface{}) int 
    } 

这并不提供类型安全的参数距离(),但是,这必须是同一类型的。例如,我可能有一个实现Distance()的SpecificTime结构;传递另一个ParticularTime对象作为参数是有道理的,但传递一个ParticularLocation根本没有意义。

我怀疑这可能会在编译时至少在某些情况下被捕获,例如,这显然是错误的:

x := ParticularLocation{} 
    y := ParticularTime{} 
    distance := x.Distance(y) 

有没有什么办法来表达这种限制?或者我必须在Distance()的每个实现中执行运行时类型检查?

我是以错误的方式思考这个问题吗?

+1

如果实现之间没有交叉,为什么不让它们分离接口,比如'TimeDistance','LocationDistance'? – JimB

+0

这是一个给我学习的作品。要求是代码的另一部分接受任何抽象的“协调”类型的东西。看看我们将如何使用它,实现将在这个Distance()方法上重叠。 – SAyotte

+0

我想你想距离(其他Distancer)int不是说这有助于原始问题 –

回答

3

这是expression problem的同态性。如果我们假设距离意味着euclidean distance,这也是相对容易概括的,这对于广泛的应用是合理的假设。由于Go不支持dependent types或任何想象的东西,但我们必须在我们希望支持的尺寸数量上作出合理的折中,以支持类型安全。

让我们对前三个维度实施此操作。

type OneVectorer interface { 
    Vector() [1]float64 
} 

type TwoVectorer interface { 
    Vector() [2]float64 
} 

type ThreeVectorer interface { 
    Vector() [3]float64 
} 

然后三个类型安全的方法:

func OneDimensionalDistance(a OneVectorer, b OneVectorer) float64 { 
    return euclideanDistance(a.Vector()[:], b.Vector()[:]) 
} 

func TwoDimensionalDistance(a TwoVectorer, b TwoVectorer) float64 { 
    return euclideanDistance(a.Vector()[:], b.Vector()[:]) 
} 

func ThreeDimensionalDistance(a ThreeVectorer, b ThreeVectorer) float64 { 
    return euclideanDistance(a.Vector()[:], b.Vector()[:]) 
} 

func euclideanDistance(a, b []float64) float64 { 
    // invariant: a and b have same length 
    c := 0.0 
    for i, _ := range a { 
     c += math.Pow(b[i]-a[i], 2) 
    } 
    return math.Sqrt(c) 
} 

所以,在某个时间点可以是OneVectorer,笛卡尔点TwoVectorer,等等...

你可以定义更多类型以方便您使程序更具表现力,并在其方法中映射到此矢量运算。

相关问题