非可选的展开值

Posted

技术标签:

【中文标题】非可选的展开值【英文标题】:Unwrap value of non-optional 【发布时间】:2021-06-30 21:47:41 【问题描述】:
var OpDoub:Optional<Double> = 1.23

func noopt(_ pp: Any) -> Any  
    return pp

var p:Any = noopt(OpDoub)
print(p)  // Optional(1.23)
print(p!) // error: cannot force unwrap value of non-optional type 'Any'

我可以在声明一个 P 后得到 1.23 的值吗? 我试过了:

var pp:Any? = p
print(pp)  // Optional(Optional(1.23)) it turned out even worse :D
print(pp!) // Optional(1.23)

【问题讨论】:

你到底想问什么? 我可以将p:Any 转换为p:Any? 以获得1.23。有可能吗? 可选只是另一种值,它们本身可以分配一个Any。这可能会导致令人困惑的行为,这就是为什么这样做会引发编译器警告。您忽略了该警告,因此现在您看到了令人困惑的行为。那么你到底想达到什么目的呢? 【参考方案1】:

如果你想得到只是

1.23

...那么您应该将downcast p 转为Double

var OpDoub:Optional<Double> = 1.23

func noopt(_ pp: Any) -> Any  
    return pp

var p:Any = noopt(OpDoub)
    
if let doubleP = p as? Double  /// here!
    print(doubleP) /// result: 1.23


编辑

如果您想解开p(使其不是可选的)并将其转换为字符串,那么试试这个(基于this awesome answer):

func unwrap(_ instance: Any) -> Any 
    let mirror = Mirror(reflecting: instance)
    if mirror.displayStyle != .optional 
        return instance
    
    
    if mirror.children.count == 0  return NSNull() 
    let (_, some) = mirror.children.first!
    return some


let unwrappedP = unwrap(p)
let string = "\(unwrappedP)" /// using String Interpolation https://docs.swift.org/swift-book/LanguageGuide/StringsAndCharacters.html#ID292
print("unwrapped string: \(string)")

结果:

解包字符串:1.23

【讨论】:

不错的解决方案。如果我不知道 OpDoub 中的原始数据类型?有没有办法不检查每种数据类型?我想立即将任何类型的数据转换为字符串...

以上是关于非可选的展开值的主要内容,如果未能解决你的问题,请参考以下文章

iOS Core Data - 用于将关系从非可选更改为可选的轻量级迁移

问题:我的非可选变量为零。 (展开时出现致命错误)

创建非可选的防范措施以测试防护条件[重复]

Swift之深入解析如何处理非可选的可选项类型

Xcode NSManagedObject 子类在它们被标记为非可选时包含可选

Swift 中的相互非可选引用循环