任何?不正确的语义

问题描述 投票:1回答:3

我当时正在快速处理一些代码,并遇到了一个有趣的案例。让我们从一些前言开始:假设您创建了一些可选变量:

let a: String? = "abcd"; let b: Int? = 4
print(
    "Type of \(a) is \(type(of: a))" //Type of Optional("abcd") is Optional<String>
    "Type of \(b) is \(type(of: b))", //Type of Optional(4) is Optional<Int>
    separator: "\n"
)

然后您强制解开包装,因此aubu的类型不是可选的。

let au = a!; let bu = b!
print(
    "Type of \(au) is \(type(of: au))", //Type of abcd is String
    "Type of \(bu) is \(type(of: bu))", //Type of 4 is Int

    au + String(bu), //abcd4
    separator: "\n"
)

似乎合理,但是当您尝试将相同的代码应用于Optional<Any>时,事情开始变得怪异:

let a: Any? = "abcd"; let b: Any? = 4
let au = a!; let bu = b!
print(
    "Type of \(a) is \(type(of: a))", //Type of Optional("abcd") is Optional<Any>
    "Type of \(b) is \(type(of: b))", //Type of Optional(4) is Optional<Any>
    "Type of \(au) is \(type(of: au))", //Type of abcd is String
    "Type of \(bu) is \(type(of: bu))", //Type of 4 is Int
    //au + String(bu),
    separator: "\n"
)

但是现在,如果您尝试执行相同的串联au + String(bu),则swift将产生编译错误,即使已知这两个变量具有某些具体类型,如swift本身所报告。错误是:

error: protocol type 'Any' cannot conform to 'LosslessStringConvertible' because only concrete types can conform to protocols

这肯定看起来像是个错误,不是吗。请分享您的意见。

swift any forceunwrap swift-optionals
3个回答
0
投票

type(of:T)方法获取任何变量的运行时类型。这就是为什么您看到(type(of:au)as String。但是出于安全原因,Swift不允许隐式类型转换。这就是为什么您不能在Swift中不进行转换就不能添加Int和Double的原因。您需要为您的代码可以正常工作。


0
投票

type(of: T)返回值的动态类型。


0
投票

[正如其他人指出的,type(of:)是值的动态运行时类型。编译器仅依赖于值的静态可证明类型。在上面的代码中,编译器唯一可以证明的是au的类型为Any。符合Any的许多类型之一是String,但是编译器并不知道在所有可能的代码路径中,值实际上都是String。

© www.soinside.com 2019 - 2024. All rights reserved.