2016-07-23 68 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