【问题标题】:Type casting and inspection query型式铸造及检验查询
【发布时间】:2017-11-15 07:32:24
【问题描述】:

我目前正在学习 swift 4 中的类型转换和检查的基础知识。我在 Apple Developer book 中找到了一个示例,我需要一些帮助。

他们有一个练习来创建一个 Any 类型的字典,然后解开遍历字典的值。给定的解决方案显示了 for 循环,括号中的值和每个值都被解包。有人可以解释所显示的解决方案吗?还有另一种(简单的)方法可以解决这个问题吗?书上的资料不够多。

let anythingAndEverything: [String: Any] = ["FirstBool": true, 
"FalseBool": false, "Unknown": "90", "AnInteger": 12, "ADouble": 1.1]

print(anythingAndEverything)

var total: Double = 0
for (_, value) in anythingAndEverything {
    if let value = value as? Bool {
        if value {
            total += 2
        } else {
            total -= 3
        }
    } else if let value = value as? Double {
        total += value
    } else if let value = value as? Int {
        total += Double(value)
    } else if let value = value as? String {
        total += 1
    }
}

print(total)

非常感谢您提前提供的任何帮助 :-)

【问题讨论】:

    标签: swift types casting


    【解决方案1】:

    Dictionary 符合Collection,它符合Sequence。这意味着可以使用 for...in 循环来循环字典。

    Dictionary的定义中,有这样一行:

    public typealias Element = (key: Key, value: Value)
    

    这意味着“在称为字典的集合中,它包含(key: Key, value: Value) 类型的元素”。这意味着您将在in 之前获得(key: Key, value: Value) 作为变量的类型:

    for element in someDictionary {
        // element is of type (key: Key, value: Value)
    }
    

    由于element 是一个元组,我们实际上可以这样解开元组:

    for (key, value) in someDictionary {}
    

    在您的具体情况下,我们不需要key 位,所以我们写_ 表示“扔掉这个”:

    for (_, value) in someDictionary {}
    

    解决此问题的另一种方法是使用reduce。我不会说这一定更简单:

    total = anythingAndEverything.reduce(0.0) { (x, y) -> Double in
        if let value = y.value as? Bool {
            if value {
                return x + 2
            } else {
                return x - 3
            }
        } else if let value = y.value as? Double {
            return x + value
        } else if let value = y.value as? Int {
            return x + Double(value)
        } else if let value = y.value as? String {
            return x + 1
        } else {
            return x
        }
    }
    

    【讨论】:

    • 谢谢@Sweeper,它确实澄清了我的一些困惑。我将对您上面建议的 reduce 解决方案进行实验,看看我是否可以找到一个可以工作的示例。
    【解决方案2】:

    另外,我建议你阅读Apple's Swift guide的官方解释。还有一个很好的示例循环遍历 Collection 并使用 switch statement 检查值的类型。

    for thing in things {
        switch thing {
        case 0 as Int:
            print("zero as an Int")
        case 0 as Double:
            print("zero as a Double")
        case let someInt as Int:
            print("an integer value of \(someInt)")
        case let someDouble as Double where someDouble > 0:
            print("a positive double value of \(someDouble)")
        case is Double:
            print("some other double value that I don't want to print")
        case let someString as String:
            print("a string value of \"\(someString)\"")
        case let (x, y) as (Double, Double):
            print("an (x, y) point at \(x), \(y)")
        case let movie as Movie:
            print("a movie called \(movie.name), dir. \(movie.director)")
        case let stringConverter as (String) -> String:
            print(stringConverter("Michael"))
        default:
            print("something else")
        }
    }
    

    这部分我也想解释一下:

    case let varName as TypeName
    

    这意味着如果新的varName 等于thing 的非可选版本并且也是TypeName 类型,则使用它执行下一个。

    【讨论】:

    • 谢谢 Stepan :-) 我已经通读了 Apple Swift 指南中的示例,但仍在苦苦挣扎。我将尝试使用 case let 进行一些练习。你上面的例子看起来很简单。
    猜你喜欢
    • 2018-08-30
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-11-23
    • 1970-01-01
    • 1970-01-01
    • 2023-04-05
    • 1970-01-01
    相关资源
    最近更新 更多