Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/swift/18.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Arrays 是否可以在Swift中创建一个仅限于一个类的数组扩展?_Arrays_Swift_Ios8 - Fatal编程技术网

Arrays 是否可以在Swift中创建一个仅限于一个类的数组扩展?

Arrays 是否可以在Swift中创建一个仅限于一个类的数组扩展?,arrays,swift,ios8,Arrays,Swift,Ios8,我可以做一个数组扩展,例如只应用于字符串吗?更新:请参阅下面Martin的答案,了解Swift 2.0更新。(我不能删除此答案,因为它已被接受;如果道格可以接受马丁的答案,我将删除此答案以避免将来的混淆。) 这在论坛上已经出现过好几次了,答案是不,你今天不能这样做,但是他们知道这是一个问题,他们希望在将来改进这一点。他们希望向stdlib中添加的某些内容也需要这样做。这就是为什么有这么多免费函数是stdlib。大多数都是解决这个问题或“无默认实现”问题(即“traits”或“mixin”)的解

我可以做一个数组扩展,例如只应用于字符串吗?

更新:请参阅下面Martin的答案,了解Swift 2.0更新。(我不能删除此答案,因为它已被接受;如果道格可以接受马丁的答案,我将删除此答案以避免将来的混淆。)



这在论坛上已经出现过好几次了,答案是不,你今天不能这样做,但是他们知道这是一个问题,他们希望在将来改进这一点。他们希望向stdlib中添加的某些内容也需要这样做。这就是为什么有这么多免费函数是stdlib。大多数都是解决这个问题或“无默认实现”问题(即“traits”或“mixin”)的解决方案。

尽管在注释中有许多请求,但您仍然没有给出用例,因此很难知道您要的是什么。但是,正如我在评论中已经说过的(Rob在回答中也说过),你不会从字面上理解它;扩展不是那样工作的(目前)

正如我在评论中所说,我要做的是将数组包装在一个结构中。现在,结构保护并保证字符串的类型,我们进行了封装。这里有一个例子,当然你必须记住,你没有给出你真正想做的事情的指示,所以这可能不是直接令人满意的:

struct StringArrayWrapper : Printable {
    private var arr : [String]
    var description : String { return self.arr.description }
    init(_ arr:[String]) {
        self.arr = arr
    }
    mutating func upcase() {
        self.arr = self.arr.map {$0.uppercaseString}
    }
}
以下是如何称呼它:

    let pepboys = ["Manny", "Moe", "Jack"]
    var saw = StringArrayWrapper(pepboys)
    saw.upcase()
    println(saw)

因此,我们已经有效地将字符串数组隔离到一个世界中,在这个世界中,我们可以使用只适用于字符串数组的函数来武装它。如果pepboys不是一个字符串数组,我们就不能从一开始就将其包装在StringArrayRapper中。

从Swift 2开始,这可以通过协议扩展来实现, 为一致性类型提供方法和属性实现 (可选地受到附加约束的限制)

一个简单的例子:为所有类型定义一个方法 到
SequenceType
(例如
Array
),其中sequence元素是
字符串

extension SequenceType where Generator.Element == String {
    func joined() -> String {
        return "".join(self)
    }
}

let a = ["foo", "bar"].joined()
print(a) // foobar
不能直接为
struct Array
定义扩展方法,只能为所有类型定义扩展方法 符合某些协议(带有可选约束)。这么一个 必须找到
Array
符合的协议,并提供所有必要的方法。在上面的示例中,即
SequenceType

另一个示例(的变体):

扩展集合类型,其中生成器。元素:可比较,索引:RandomAccessIndexType{ typealias T=生成器.Element func insertionIndexOf(elem:T)->索引{ var lo=自启动索引 var hi=self.endIndex 你好{ //中=低+(高-1-低)/2 让mid=lo.advancedBy(lo.distanceTo(hi.PRESIONER())/2) 如果self[mid] 这里,该方法被定义为
CollectionType
的扩展,因为 需要对元素进行下标访问,并且元素是
要求具有可比性这一点已经得到了上述三位智者的回答;-),但我谦恭地概括了@Martin的答案。我们可以通过使用“标记”协议来定位任意类,该协议只在我们希望定位的类上实现。也就是说,我们不需要找到一个协议本身,但可以创建一个简单的协议,用于针对所需的类

protocol TargetType {}
extension Array:TargetType {}

struct Foo  {
    var name:String
}

extension CollectionType where Self:TargetType, Generator.Element == Foo {
    func byName() -> [Foo] { return sort { l, r in l.name < r.name } }
}

let foos:[Foo] = ["c", "b", "a"].map { s in Foo(name: s) }
print(foos.byName())
协议目标类型{}
扩展数组:TargetType{}
结构Foo{
变量名称:String
}
扩展集合类型,其中Self:TargetType,Generator.Element==Foo{
func byName()->[Foo]{返回排序{l,r在l.name
不确定您的意思-您能详细说明您的意图吗?也许是一个例子?@dpassage您可以根据扩展类遵守协议()的要求进行扩展,我很好奇您是否可以进一步将其限制为仅限于一个类,以便我在Swift中的扩展仅适用于字符串数组。但请描述您希望这种扩展做什么。这只是一个函数的问题吗?然后定义一个全局泛型函数。给出一个你希望实现的实际用例。是的,它只是一个函数。你能描述一下那会是什么样子吗?如果我理解正确,我必须传入数组,这不是最优的。它看起来像内置函数。看看
find
在元素只能相等的数组上是如何工作的。谢谢,这看起来确实有点奇怪。我会祈求好运的。可能想在2.0版中编辑这个,特别是当重复引用它时。如果数组可能很大,则类可能比结构更好,这样可以保证通过引用传递。出于这个原因,我经常将大数组包装在类中,这样传递它们就不需要复制。Swift使用“写时拷贝”作为传递值,因此在大多数情况下传递大数组不会产生太大的成本。如果你发现一个主要的成本,你应该打开一个雷达。苹果公司特别指出,你不应该因为性能原因而回避复制。请参见@RobNapier底部的注释此处的属性是一个
var
,示例假设它将被写入。您可以将
Index==Int
切换到
Index:RandomAccessIndexType
,并进行一些小的更改,例如
startIndex
而不是
0
endIndex.preference()
让mid=lo.advancedBy(lo.distanceTo(hi)/2)
加上提前保释
是空的
。例如,这意味着它将与
protocol TargetType {}
extension Array:TargetType {}

struct Foo  {
    var name:String
}

extension CollectionType where Self:TargetType, Generator.Element == Foo {
    func byName() -> [Foo] { return sort { l, r in l.name < r.name } }
}

let foos:[Foo] = ["c", "b", "a"].map { s in Foo(name: s) }
print(foos.byName())