2016-07-23 81 views
6

我正在尝试编写[String]的扩展方法。[String]的Swift扩展?

看来你不能直接扩展[String](“类型‘元素’限制非协议类型‘字符串’”),虽然我遇到了这个窍门:

protocol StringType { } 
extension String: StringType { } 

但我仍然可以”牛逼相当使雨燕系统满意这个:

extension Array where Element: StringType { 
    // ["a","b","c","d","e"] -> "a, b, c, d, or e". 
    func joinWithCommas() -> String { 
     switch count { 
     case 0, 1, 2: 
      return joinWithSeparator(" or ") 
     default: 
      return dropLast(1).joinWithSeparator(", ") + ", or " + last! 
     } 
    } 
} 

joinWithSeparator电话是“暧昧”。我试过所有我能想到的东西,比如使用(self as! [String])(和一些类似的变体),但似乎没有任何工作。

如何让Swift编译器对此感到满意?

回答

6

你可以按照joinWithSeparator(点击它)的声明并且发现它被定义为协议SequenceType的扩展,而不是类型Array

// swift 2: 
extension SequenceType where Generator.Element == String { 
    public func joinWithSeparator(separator: String) -> String 
} 

注:在Xcode中8 /斯威夫特3,如果你在join(separator:) Cmd的点击,你将降落在Array即使是still implemented inside Sequence,但不会低于无效的想法)

我们可以做同样的你的功能,在这里我们通过扩展阵列,而不是阵列本身采用了协议:

// swift 2: 
extension CollectionType where 
     Generator.Element == String, 
     SubSequence.Generator.Element == String, 
     Index: BidirectionalIndexType 
{ 
    func joinWithCommas() -> String { 
     switch count { 
     case 0, 1, 2: 
      return joinWithSeparator(" or ") 
     default: 
      return dropLast(1).joinWithSeparator(", ") + " or " + last! 
     } 
    } 
} 

// swift 3: 
extension BidirectionalCollection where 
     Iterator.Element == String, 
     SubSequence.Iterator.Element == String 
{ 
    func joinWithCommas() -> String { 
     switch count { 
     case 0, 1, 2: 
      return joined(separator: " or ") 
     default: 
      return dropLast().joined(separator: ", ") + " or " + last! 
     } 
    } 
} 

注:

  • 我们扩展CollectionType能够使用count
  • 我们约束Generator.Element == String使用joinWithSeparator
  • 我们约束SubSequence.Generator.Element == String确保dropLast(1)可以使用joinWithSeparatordropLast(1)返回关联的类型SubSequence
  • 我们约束Index: BidirectionalIndexType使用last
+0

的详细程度。 POP有它的副作用。感谢您的解决方案✌️ – eonist

5

在夫特3.1(8.3.2 Xcode的),可以简单地扩展阵列,其中元件类型等于字符串

extension Array where Element == String { 
    var joinedWithCommas: String { 
     guard let last = last else { return "" } 
     return count > 2 ? dropLast().joined(separator: ", ") + " or " + last : joined(separator: " or ") 
    } 
} 

["a","b","c"].joinedWithCommas // "a, b or c" 
+1

我们很快就会说。“记住我们不得不......”的旧时代 – Fattie