2016-09-25 27 views
0

在PluralSight課程「Swift First Look」中,有一個關於Enums的部分,它似乎已過時。提供的代碼是這樣的:如何更正此Swift枚舉?

//: Playground - noun: a place where people can play 

import UIKit 

enum CardType: String { 
    case AmericanExpress = "AmericanExpress" 
    case Visa = "Visa" 
    case Discover = "Discover" 
    case MasterCard = "MasterCard" 
    case None = "None" 

    private func regularExpression() -> NSRegularExpression { 
     switch self { 
     case .Visa: 
      return NSRegularExpression(pattern: "^4[0-9]{12}(?:[0-9]{3})?$", options: nil, error: nil) 
     case .AmericanExpress: 
      return NSRegularExpression(pattern: "^4[47][0-9]{13}$", options: nil, error: nil) 
     case .MasterCard: 
      return NSRegularExpression(pattern: "^5[1-5][0-9]{14}$", options: nil, error: nil) 
     case .Discover: 
      return NSRegularExpression(pattern: "^6(?:011|5[0-9]{2})[0-9]{12}$", options:nil, error:nil) 
     default: 
      return NSRegularExpression(pattern: ".*", options:nil, error:nil) 
     } 
    } 

    func isValidFor(cardNumber: String) -> Bool { 
     let re = self.regularExpression() 
     let range = NSRange(0..<cardNumber.lengthOfBytes(using: String.Encoding.utf8)) 
     let matches = re.numberOfMatches(in: cardNumber, options: .anchored, range: range) 
     return matches > 0 
    } 

    static let allValues = [Visa, AmericanExpress, Discover, MasterCard] 

    static func from(cardNumber: String) -> CardType? { 
     for type in self.allValues { 
      if type.isValidFor(cardNumber: cardNumber) { 
       return type 
      } 
     } 
    } 
} 

CardType.Visa.isValidFor(cardNumber: "4242424242424242") 
CardType.Visa.isValidFor(cardNumber: "1234") 

CardType.from(cardNumber: "4242424242424242").rawValue 

這樣做的問題是,在開關塊中的return語句都有這個錯誤的最新版本的Xcode報道:

Type of expression is ambiguous without more context 

而且,最後一行報告此錯誤:

Value of optional type 'CardType?' not unwrapped; did you mean to use '!' or '?'? 

我該如何解決這個問題?Swift的當前版本需要什麼?

注意:是的,我剛剛開始使用Swift。

+0

你使用的是什麼版本的Swift?或者什麼版本的Xcode。你所顯示的代碼是爲Swift 1.x編寫的,因爲Swift語言正在變得如此迅速,它也太老了,以致於無法學習。 Swift的最新版本是3.0附帶的Xcode 8.如果你找不到更新的課程,你需要面對類似的問題很多次。 – OOPer

+0

我使用的是最新的XCode Swift,但課程是從2014年開始的。我只需要知道要做出什麼樣的更改。 –

+0

一般來說,「爲我做一切事情」的問題在這裏不受歡迎。該代碼是爲Swift 1.x編寫的,你說你正在使用最新的Xcode,這意味着你正在使用Swift 3.在展示你迄今爲止所做的工作之後,你會得到更好更快的響應。 – OOPer

回答

1

NSRegularExpression()初始化程序已更改。您必須通過[]而不是nil(但由於這是默認值,因此您可以完全忽略options),並且必須處理它可能導致錯誤的事實。既然你處理的是不會失敗的靜態模式,你可以用try!來調用它們。通常情況下,這是很危險的,因爲如果返回錯誤它會崩潰。有了這些靜態模式,這種情況不會發生(或者當它發生時你會修復它)。

變化:

return NSRegularExpression(pattern: "^4[0-9]{12}(?:[0-9]{3})?$", options: nil, error: nil) 

到:

return try! NSRegularExpression(pattern: "^4[0-9]{12}(?:[0-9]{3})?$") 

和重複所有NSRegularExpressions的。

最後一行,你只需要一個?

CardType.from(cardNumber: "4242424242424242")?.rawValue 

最後,這一功能需要一個return nil考慮的情況下,當在for循環沒有找到CardType

static func from(cardNumber: String) -> CardType? { 
    for type in self.allValues { 
     if type.isValidFor(cardNumber: cardNumber) { 
      return type 
     } 
    } 
    return nil 
} 
+0

謝謝 - 這很有幫助!正是我需要的。這些錯誤確實需要一些習慣,但至少這些現在是有道理的。 –

+0

不客氣。自Swift 1.1以來發生了很多變化。 Swift 2.2 - > 3.0的過渡對於API來說是另一個巨大的過渡。自動填充是你的朋友。對於已更改(以及幾乎所有內容)的這些API,請嘗試從頭開始鍵入它們並查看Autocomplete的建議。 – vacawama

+0

很酷,謝謝!儘可能多地使用自動完成功能,但這是異類的錯誤。 Mac上的編碼對我來說是新的,但編碼不是。順便說一句,當我把return.None而不是返回零我得到的錯誤'None'已被重命名爲'無',但將一個不同的CardType返回值是好的。但我可以明確地把CardType.None。 –