Swift:使用Obj-C类

时间:2014-08-08 01:26:18

标签: swift

我在Playground中玩Swift,我创建了一个简单的代码,用于翻译OneTwoThree123之类的字符串。
一开始,我通过检查for循环中每个char的大写/小写状态来实现它,然后我尝试使用正则表达式:

let regExPattern = "(?<=(^|[a-z]))[A-Z][a-z]+(?=([A-Z]|$))"
let regEx = NSRegularExpression(pattern: regExPattern, options: nil, error: nil)

let numbersRegEx = numberNames.map({(name: String) -> Int in

    let matches = regEx.matchesInString(name, options: nil, range: NSMakeRange(0, countElements(name)))

    let digits = matches.map({(match:AnyObject) -> String in

        // lookupString return a String containing
        // the digit corresponding to the passed digit name
        // e.g.  lookupString("Three") -> "3"

        return lookupString(name[match.range.toRange()!.startIndex ..< 
                                 match.range.toRange()!.endIndex])

    })
    return String().join(digits).toInt()!

})

我不明白为什么matchesInString给了我一个[AnyObject]代替[NSTextCheckingResult],我敢打赌,因为我收到了一个Obj -C对象,不是吗?

2 个答案:

答案 0 :(得分:1)

matchesInString的官方Apple文档说:

- (NSArray *)matchesInString:(NSString *)string options:(NSMatchingOptions)options range:(NSRange)range

鉴于此签名,Swift无法知道您的数组只包含某种类型的对象

因为它无法知道,Swift编译器必须将它转换为最通用的结果类型,这是一个AnyObject数组(你至少知道只有对象会存在,因为该方法起源于目标-C)。

因此[AnyObject]选择。 而且,实际上,如果没有关于生成的NSArray的任何可空性信息,您获得的内容可能更接近[AnyObject]! (NSArray *很可能是零,再次缺少可空性信息) - 数组中的单个对象不能为零(NSArray不支持nil作为元素),所以假设Swift知道那个,那里AnyObjects不需要自己作为IOO

答案 1 :(得分:1)

你得到一个AnyObject数组,因为当Swift有类型数组时(由于它的泛型支持),Objective-C只有非类型NSArray,它可以包含任何类型的对象。文档指出matchesInString()返回NSTextCheckingResult个对象的数组,但编译器不会从Objective-C方法签名中知道这一点:

- (NSArray *)matchesInString:(NSString *)string
                     options:(NSMatchingOptions)options
                       range:(NSRange)range

但是,您可以将此返回值强制转换为NSTextCheckingResult数组,如下所示:

let matches = regEx.matchesInString(name, options: nil, 
        range: NSMakeRange(0, countElements(name))) as [NSTextCheckingResult]

不幸的是,如果没有任何回复,这会给你一个运行时错误,因为nil无法转换为数组,所以你最好让matches成为一个可选:

let matches = regEx.matchesInString(name, options: nil, 
        range: NSMakeRange(0, countElements(name))) as? [NSTextCheckingResult]

或使用可选绑定来安全地访问任何结果(这很好,因为您可以在else中轻松处理“未找到案例”):

if let matches = regEx.matchesInString(name, options: nil, 
        range: NSMakeRange(0, countElements(name))) as? [NSTextCheckingResult] {
    // process the matches
} else {
    // invalid number string
}