[英]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
不在字典中并且wantsGroundAlways
为false
则它通过测试。
if let
or guard let
is not needed either because according the condition the value for key is never used. if let
不需要if let
或guard let
,因为根据条件从不使用key的值。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.