我可以创建一个适用于(例如)字符串的数组扩展吗?是否可以在Swift中创建一个数组扩展?
回答
作为夫特2的,但是现在可以用协议扩展, ,其对符合类型 (任选被附加约束限制)提供方法和属性的实现来实现。
一个简单的例子:定义符合所有类型的方法 到SequenceType
(如Array
),其中序列元件是String
:
extension SequenceType where Generator.Element == String {
func joined() -> String {
return "".join(self)
}
}
let a = ["foo", "bar"].joined()
print(a) // foobar
扩展方法不能用于struct Array
定义直接,但只适用于符合某些协议(具有可选约束)的所有类型 。所以一个 必须找到协议Array
符合,并提供所有必要的方法。在上例中,即SequenceType
。
又如(的How do I insert an element at the correct position into a sorted array in Swift?的变化):
extension CollectionType where Generator.Element : Comparable, Index : RandomAccessIndexType {
typealias T = Generator.Element
func insertionIndexOf(elem: T) -> Index {
var lo = self.startIndex
var hi = self.endIndex
while lo != hi {
// mid = lo + (hi - 1 - lo)/2
let mid = lo.advancedBy(lo.distanceTo(hi.predecessor())/2)
if self[mid] < elem {
lo = mid + 1
} else if elem < self[mid] {
hi = mid
} else {
return mid // found at position `mid`
}
}
return lo // not found, would be inserted at position `lo`
}
}
let ar = [1, 3, 5, 7]
let pos = ar.insertionIndexOf(6)
print(pos) // 3
这里所述方法被定义为扩展到CollectionType
因为需要 的元素下标访问,并且这些元件被要求 为Comparable
。
您可以将'Index == Int'切换为'Index:RandomAccessIndexType',并稍作修改。 'startIndex'而不是'0','endIndex.predecessor()','let mid = lo.advancedBy(lo.distanceTo(hi)/ 2)'加上'isEmpty'上的提前保释。这意味着例如它可以与'String.UTF16View'一起使用,它是随机访问但不是整数索引。 – 2015-06-12 04:57:26
@AirspeedVelocity:完成:) – 2015-06-12 06:16:43
更新:请参阅下面的关于Swift 2.0更新的Martin的回答。 (因为它被接受,我不能删除这个答案;如果道格可以接受马丁的回答,我会删除这一项,以避免将来出现混乱。)
这已经拿出了多次在论坛,答案是否定的,你今天不能这样做,但他们认为这是一个问题,他们希望在将来改进这一点。有些东西他们想要添加到stdlib,也需要这个。这就是为什么有这么多的免费功能是stdlib。他们大多数都是针对这个问题或“无默认实现”问题(即“特征”或“mixins”)的变通方法。
谢谢,它确实看起来像一个奇怪的遗漏。将保持我的手指交叉。 – 2014-12-08 03:42:36
可能要编辑这个2.0,特别是。因为愚蠢指的是它。 – 2015-06-12 04:58:48
尽管在评论中有很多请求,但您仍然没有给出用例,因此很难知道您要做什么。但是,正如我已经在评论中所说的(而罗布在回答中说过),你不会从字面上理解它;扩展不能以这种方式工作(目前)。
正如我在评论中所说,我会做的是将数组包装在结构中。现在结构保护并保证字符串的类型,并且我们有封装。下面是一个例子,但当然,你必须保持你已经没有给出这种事情你真的喜欢做的指示头脑,所以这可能不是直接满足:
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
不是字符串数组,我们不能将它包装在StringArrayWrapper中以开始。
如果数组可能很大,那么一个类可能比一个结构更好,这样就保证了通过引用传递。为了这个原因,我常常在类中包装大数组 - 所以传递它们不涉及复制。 – matt 2014-12-08 15:25:42
Swift使用copy-on-write进行按值传递,因此在大多数情况下,传递大型数组不应该花费大量成本。如果你发现一个重要的成本,你应该打开一个雷达。苹果特别指出,出于性能原因,你不应该试图躲避复制。请参阅https://developer.apple.com/library/ios/documentation/Swift/Conceptual/Swift_Programming_Language/ClassesAndStructures.html底部的说明。 – 2014-12-08 18:33:12
@RobNapier这里的属性是一个'var',并且该示例假定它会被写入。 – matt 2014-12-08 18:42:58
这已经被上面三位智者的回答;-),但我虚心地提供了@马丁的答案的概括。我们可以通过使用仅在我们希望定位的类上实现的“标记”协议来定位任意类。 IE浏览器。一个不必找到一个协议本身,但可以创建一个微不足道的用于定位所需的类。
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())
- 1. 是否可以创建一个可扩展列表AlertDialog?
- 2. 是否可以从Pascal中的数组创建一个数组?
- 3. 是否可以在C#中创建扩展运算符?
- 4. 是否可以在Haskell中创建PHP扩展?
- 5. 是否可以在JavaFX中创建一个控制器数组?
- 6. 是否可以在WatchKit中创建一个按钮数组?
- 7. 是否可以在Java中创建一个BufferedWriters数组?
- 8. 是否可以在TCL中创建一个列表数组?
- 9. 是否可以在C#中扩展数组?
- 10. 扩展组件以在另一个中创建逻辑
- 11. 是否可以在Android中扩展Canvas?
- 12. 是否可以扩展DefaultValueAccessor?
- 13. 是否可以扩展DataColumn.Expression
- 14. 是否可以从扩展
- 15. 是否可以扩展类
- 16. 是否可以在WinRT中用C++/CX创建一个数组数组?
- 17. 在Swift中创建一个数组集
- 18. 是否可以在Swift中创建“正数”类型?
- 19. 如何在Swift类扩展中创建一个'static'?
- 20. C++用指针创建一个可扩展的数组
- 21. 是否可以创建一个扩展名为“(.wav)`格式的虚拟文件?
- 22. 是否有可能为F#元组创建扩展方法
- 23. 创建一个扩展另一个PHP扩展的PHP扩展?
- 24. 是否可以使用Java创建企业Archetict扩展?
- 25. 是否可以使用Resharper创建扩展方法?
- 26. 是否可以使用2.0框架创建扩展方法?
- 27. 是否可以创建静态扩展方法
- 28. 是否可以创建一个变量名称数组?
- 29. 是否可以创建一个结构实例数组?
- 30. 是否可以创建一个开放式数组?
不确定你的意思 - 你能说更多关于你的意图吗?也许是一个例子? – dpassage 2014-12-08 03:28:15
@dpassage你可以扩展事物的扩展类遵守协议(https://developer.apple.com/library/ios/documentation/Swift/Conceptual/Swift_Programming_Language/Extensions.html),我很好奇如果你可以进一步限制它只有一个类,以便我在Swift中的扩展只适用于字符串数组。 – 2014-12-08 03:32:29
但是描述一下你想要这样的扩展到_do_。这只是一个功能问题吗?然后定义一个全局通用函数。给你一个你希望完成的实际用例。 – matt 2014-12-08 03:33:17