首页 > 解决方案 > 保护让数字作为 NSString 和 NSNumber

问题描述

我从不同来源获取数据,变量可以是数字或数字字符串。如何确保“(number as?NSString)”或“(number as?NSNumber)”总是成功?类似于 Java optInt的东西,即使数字是字符串也永远不会失败。请参见下面的示例:

func testNumber()
    {
        var number = 123
        guard let a = (number as? NSNumber)?.intValue else { print("1");return; }
    }

func testNumberString()
{
    var number = "123"
    guard let a = (number as? NSNumber)?.intValue else { print("2");return; } // this failed.
}
func testNumberToString()
{
        var number = 123
        guard let a = (number as? NSString)?.intValue else { print("2");return; } // this sometimes failed too depend on datasource.
}
    

标签: swiftnsstringnsnumber

解决方案


正如我从您的问题中了解到的那样,无论输入类型是字符串还是整数,最后都需要一个整数值。

您可以通过使用ExpressibleByStringLiteral.

这是演示

extension Int: ExpressibleByStringLiteral {
    public typealias StringLiteralType = String
    
    public init(stringLiteral value: StringLiteralType) {
        self = Int(value) ?? 0
    }
}

Int扩展允许您接受字符串值作为 Int 并返回int值。如果它没有转换它会0默认给你。

例子

func testInt() {
    let numberOne: Int = "5656"
    let numberTwo: Int = 1234
    print(numberOne)
    print(numberTwo)
}

或者另一种方法是创建自己的ExpressibleByStringLiteral,它可以帮助您根据需要提供默认值。

struct StringInt: ExpressibleByStringLiteral {
    var value: Int?
    init(stringLiteral value: String) {
        self.value = Int("\(value)")
    }
    
    func wrapped(with defaultValue: Int) -> Int {
        return self.value ?? defaultValue
    }
}

例子

func testInt() {
    var numberThree: StringInt = "5656"
    print(numberThree.value as Any) // with nil or optional value
    
    numberThree = "asf"
    print(numberThree.wrapped(with: 15)) // with default value
    
    /**
     Output
     Optional(5656)
     15
     */
}

推荐阅读