I was writing some example code in a playground and wanted a function that returns the distance between two values, both of which conform to the Strideable protocol in Swift so that I could use the distance(to other: Self) -> Self.Stride
function. My implementation was as follows:
我在操场上写了一些示例代码,想要一个函数返回两个值之间的距离,这两个值都符合Swift中的Strideable协议,这样我就可以使用距离(对其他:Self) - > Self.Stride函数。我的实施如下:
func distanceFrom<T: Strideable, U>(_ a: T, to b: T) -> U where T.Stride == U
{
return a.distance(to: b)
}
After observing this function for a while, I realized that I wasn't sure which Stride was being used in the where clause, the one from a
or from b
. From what I understand it would be possible for a
and b
to define different associated types for Stride
. Also I haven't made any statements to ensure that a.Stride == b.Stride, although I understand that I could expand my where clause to do so.
在观察了这个函数一段时间之后,我意识到我不确定在where子句中使用了哪个Stride,来自a或b的那个。根据我的理解,a和b可以为Stride定义不同的关联类型。此外,我没有做任何声明来确保a.Stride == b.Stride,虽然我知道我可以扩展我的where子句来这样做。
So, which one would get used to check equivalence to U
? To be clear, the question isn't about this particular code block, but rather any situation in which this ambiguity would exist.
那么,哪一个会习惯于检查与U的等价?需要明确的是,问题不在于这个特定的代码块,而在于存在这种模糊性的任何情况。
1 个解决方案
#1
1
a
and b
are the same type. If you wanted them to be different Strideable
types you would add another generic parameter conforming to Strideable
such that the function signature appears as follows:
a和b是相同的类型。如果您希望它们是不同的Strideable类型,您将添加符合Strideable的另一个通用参数,以便函数签名如下所示:
func bar<T: Strideable, V: Strideable, U>(_ a: T, to b: V) -> U where T.Stride == U, V.Stride == U {
return a.distance(to: a) //Trivial return statement (see explanation below)
}
Although the aforementioned code would compile, return a.distance(to: b)
would not compile because they (a
and b
) are different types and the definition of distance
in Swift3 is public func distance(to other: Self) -> Self.Stride
(note the use of Self
which restricts other
to the same type as the Strideable
upon which this function is called). In conclusion, although you could make a
and b
different types, for your application it would not make sense to do so.
虽然上面的代码会编译,但返回a.distance(to:b)不会编译,因为它们(a和b)是不同的类型,Swift3中距离的定义是公共函数距离(对于其他:Self) - > Self。 Stride(注意使用Self,将其他类型限制为与调用此函数的Strideable相同的类型)。总而言之,尽管你可以制作一个和另外两种类型,但对于你的应用来说,这样做是没有意义的。
As further evidence for not being able to call your original posted code with different types please see the attached Playground screenshot which shows an error when using different types.
作为无法使用不同类型调用原始发布代码的进一步证据,请参阅随附的Playground屏幕截图,其中显示使用不同类型时的错误。
However, this works fine in the playground.
但是,这在操场上很好用。
func distanceFrom<T: Strideable, U>(_ a: T, to b: T) -> U where T.Stride == U {
return a.distance(to: b)
}
let doubleFoo: Double = 4.5
let intFoo: Double = 4
let g = distanceFrom(doubleFoo, to: intFoo) // gives me a double of -0.5
I hope this helps.
我希望这有帮助。
#1
1
a
and b
are the same type. If you wanted them to be different Strideable
types you would add another generic parameter conforming to Strideable
such that the function signature appears as follows:
a和b是相同的类型。如果您希望它们是不同的Strideable类型,您将添加符合Strideable的另一个通用参数,以便函数签名如下所示:
func bar<T: Strideable, V: Strideable, U>(_ a: T, to b: V) -> U where T.Stride == U, V.Stride == U {
return a.distance(to: a) //Trivial return statement (see explanation below)
}
Although the aforementioned code would compile, return a.distance(to: b)
would not compile because they (a
and b
) are different types and the definition of distance
in Swift3 is public func distance(to other: Self) -> Self.Stride
(note the use of Self
which restricts other
to the same type as the Strideable
upon which this function is called). In conclusion, although you could make a
and b
different types, for your application it would not make sense to do so.
虽然上面的代码会编译,但返回a.distance(to:b)不会编译,因为它们(a和b)是不同的类型,Swift3中距离的定义是公共函数距离(对于其他:Self) - > Self。 Stride(注意使用Self,将其他类型限制为与调用此函数的Strideable相同的类型)。总而言之,尽管你可以制作一个和另外两种类型,但对于你的应用来说,这样做是没有意义的。
As further evidence for not being able to call your original posted code with different types please see the attached Playground screenshot which shows an error when using different types.
作为无法使用不同类型调用原始发布代码的进一步证据,请参阅随附的Playground屏幕截图,其中显示使用不同类型时的错误。
However, this works fine in the playground.
但是,这在操场上很好用。
func distanceFrom<T: Strideable, U>(_ a: T, to b: T) -> U where T.Stride == U {
return a.distance(to: b)
}
let doubleFoo: Double = 4.5
let intFoo: Double = 4
let g = distanceFrom(doubleFoo, to: intFoo) // gives me a double of -0.5
I hope this helps.
我希望这有帮助。