简体   繁体   English

从可选容器中提取非可选值的最佳方法

[英]Best way to pull non-optional values from optional containers

This is a best practices question, and I have a feeling I'm missing an obvious solution... 这是一个最佳实践问题,我感觉我缺少一个明显的解决方案...

I was stumped why this bit of code made it past the if when wantsGroundAlways was false and I1 was undefined: 我感到很困惑,为什么这部分代码超出了if wantsGroundAlways为false且I1未定义的if的情况:

let i = c.data["I1"]?.integerValue
if !wantsGroundAlways && i == 0 { return }

The problem was that data["I1"] is, by definition, optional, so Swift inferred i as int? 问题是data["I1"]根据定义是可选的,因此Swift将i推断为int? , and nil != 0. Subtle, but obvious in retrospect. ,并且nil!=0。微妙,但回想起来很明显。

But what is the best way to deal with this common case? 但是,处理这种常见情况的最佳方法什么? One solution is: 一种解决方案是:

let i = (c.data["I1"] ?? 0).integerValue

But personally I think that looks terrible and hides the intent. 但是我个人认为这看起来很糟糕,而且隐藏了意图。 Something along the lines of: 类似于以下内容:

guard let i = c.data["I1"]?.integerValue else { i = 0 }

would make it obvious what you're trying to do, but it doesn't work because the i cannot be accessed in the else clause and { let i = 0 } is not the same i (try it, you'll see what I mean). 可以使您清楚地知道您要做什么,但是它不起作用,因为无法在else子句中访问{ let i = 0 }并且{ let i = 0 }i不一样(尝试一下,您将看到我在做什么意思)。

Now there is this: 现在有这个:

guard let arcradius = c.data["F1"]?.doubleValue else { return }

which seems really close to what I want to do, but I'm not sure this is really what I think it means - will the return really fire if F1 is not in the dict? 这似乎确实接近我想做的事情,但是我不确定这是否真的就是我的意思-如果F1不在命令中,返回值会真正触发吗? And what is the difference between that version and this: 这个版本与这个版本有什么区别:

guard case let arcradius = c.data["F1"]?.doubleValue else { return }

Which tells me it's always true? 哪个告诉我这总是对的?

I think I am missing something key here... so what do you all do in these situations? 我想我在这里缺少一些关键...所以在这些情况下你们都做什么?

I think this is the most straightforward and expressive way of solving your first question: 我认为这是解决第一个问题的最直接,最富有表现力的方式:

let i = c.data["I1"]?.integerValue ?? 0

It doesn't require brackets, and shows intent. 它不需要括号,并且显示了意图。

?? is the nil coalescence operator . nil合并运算符 It's a binary operator. 这是一个二进制运算符。 If the left operand is not nil , it's returned, otherwise the right operand is returned. 如果左操作数不是nil ,则返回它,否则返回右操作数。

c.data["I1"] can be nil (because there might be no value for the "I1" key). c.data["I1"]可以为nil (因为"I1"键可能没有值)。 In such a case, c.data["I1"]?.integerValue will be nil . 在这种情况下, c.data["I1"]?.integerValue将为nil The ?? ?? will then return the 0 . 然后将返回0 If all goes well, and the left side isn't nil , it'll be returned, ignoring the 0 . 如果一切顺利,并且左侧不是nil ,则将其返回,忽略0

If you want only to check if a key exist or not then a "type cast" to Int or Double is irrelevant. 如果只想检查键是否存在,则与“ Int或“ Double无关的“类型转换”。

Why not simply 为什么不简单

guard c.data["I1"] == nil && !wantsGroundAlways else { return }

It passes the test if I1 is not in the dictionary and wantsGroundAlways is false . 如果I1不在字典中并且wantsGroundAlwaysfalse则它通过测试。

if let or guard let is not needed either because according the condition the value for key is never used. if let不需要if letguard let ,因为根据条件从不使用key的值。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM