Arrays 斯威夫特扮演了通用的与UInt的碰撞

Arrays 斯威夫特扮演了通用的与UInt的碰撞,arrays,generics,swift,uint,Arrays,Generics,Swift,Uint,如果使用的数组类型为UInt,为什么下面的数组扩展会崩溃,但如果数组类型为Int或String,为什么会崩溃 extension Array { func indexOf<T:Equatable>(value:T) -> Int? { for (i, val) in enumerate(self) { if (val as T == value) { return i; } }

如果使用的数组类型为UInt,为什么下面的数组扩展会崩溃,但如果数组类型为Int或String,为什么会崩溃

extension Array
{
func indexOf<T:Equatable>(value:T) -> Int?
{
    for (i, val) in enumerate(self)
    {
        if (val as T == value)
        {
            return i;
        }
    }
    return nil;
}
}

var a:[UInt] = [243, 234, 1, 212, 3, 56, 88, 11, 77];
var i = a.indexOf(234);
扩展数组
{
func indexOf(值:T)->Int?
{
对于枚举(self)中的(i,val)
{
if(val as T==值)
{
返回i;
}
}
返回零;
}
}
变量a:[UInt]=[243234 1212,3,56,88,11,77];
var i=a.indexOf(234);
产生的错误:

操场执行失败:错误:执行被中断,原因:EXC_断点(代码=EXC_I386_BPT,子代码=0x0)。 进程被留在中断的位置,请使用“thread return-x”返回到表达式求值之前的状态。 *线程1:tid=0x27a3c,0x00000001079d3f27 libswift\u stdlib\u core.dylib
swift\u dynamicCast+1063,队列='com.apple.main thread',停止原因=EXC\u断点(代码=EXC\u I386\u BPT,子代码=0x0)
*帧0:0x00000001079d3f27 libswift\u stdlib\u core.dylib
swift\u dynamicCast+1063
帧#1:0x00000001137BBC8

问题在于您定义的
T:equalable
与存储在数组中的
T
无关。当您将
val设置为T
时,您将从数组值类型转换为需要相等的新本地
T

使用文本调用
indexOf
时,不会将其强制为与
a
中存储的类型相同的类型,因为扩展名不会强制该类型匹配

最好使用函数获取数组中对象的索引:

func indexOfObject<T : Equatable>(object: T, inArray collection: [T]) -> Int? {
    var index : Int = 0
    for testObject in collection {
        if testObject == object {
            return index
        }
        index++
    }
    return nil
}
这更灵活,允许您执行以下操作:

var i = a.indexOfObjectPassingTest({$0 == 234})

还请注意,我没有为我的方法定义
T
,因为它已经在数组本身中定义了。

与您之前(现在已删除)的问题的区别在哪里?与我之前问题中的注释相比,您的注释的相关性在哪里?!可能重复感谢您的快速解释和示例!似乎扩展不适用于此。也许我还没有看到灵活性,但我认为对于简单的indexOf调用,闭包不应该是必需的。@Avalon,闭包在这种情况下只是“必需的”,因为您不能保证存储在数组中的所有类型都是相等的。它为您提供了额外的灵活性,可以使用一种方法进行无限类型的测试来查找对象。例如,可以使用
{$0>234}
查找大于234的第一个索引。您还可以对存储引用类型(类类型)的数组使用
{$0===someObj}
!是的,这很灵活。谢谢你的信息。我会考虑两种方法。
var i = a.indexOfObjectPassingTest({$0 == 234})