2016-09-25 62 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。 –