- Java 双重比较
- java - 比较器与 Apache BeanComparator
- Objective-C 完成 block 导致额外的方法调用?
- database - RESTful URI 是否应该公开数据库主键?
好吧,所以我知道在 Swift 中使用可选值的正常方法是通过可选绑定(bind)来解包它们,就像这样......
let stringA:String? = nil // (or "ABC")
if let unwrappedStringA = stringA
{
let x:String = unwrappedStringA
}
但我也看到了以下使用隐式解包选项的方式,我个人认为它看起来更干净,因为它不仅不需要额外的变量,而且它“读起来”更好,更像英语(即 '如果这不是零,那么...') 并且可读性是 Swift 的核心原则之一(尤其是在即将到来的 Swift 3.0 中)。
let stringA:String! = nil // (or "ABC")
if stringA != nil
{
let x:String = stringA
}
然而,对于后者,Swift 的“纯粹主义者”将其称为“代码味道”并坚持认为它是“糟糕、糟糕、糟糕!!”……但他们从不解释原因!那么……为什么这么糟糕?
注意:是的,我知道可选链接和其他不能与隐式解包可选一起使用的功能,它们都是非常酷的功能,但我特别询问测试的技术缺点针对 nil 与可选绑定(bind)的隐式解包选项。
我希望的是可量化的技术原因,说明一个比另一个更好(即编译器优化、更好的安全检查、性能等)。换句话说,不仅仅是“嘿,因为那是不是“swift ”的方式来做到这一点!希望这是有道理的。
实际上,我只是找到了一种方法来解决我的一个问题(至少是表面上的),即必须创建一个新变量来保存未包装的变量。这里的技巧是因为展开的变量实际上与可选变量本身在不同的范围内,您可以使用完全相同的名称。
此外,括号内还有另一个作用域,它也可以有一个名为 stringA 的变量。这意味着您现在可以拥有三个“stringA”变量(但并不意味着您应该!)...
这是一段疯狂的代码,展示了这一点......
let stringA:String? = nil // (or "ABC") // First stringA variable
if let stringA = stringA
{
let x:String = stringA // <- This stringA is the unwrapped optional (the second stringA)
// Now we're just getting crazy (and smelly!)
let stringA = stringA + stringA // <- This is yet another stringA (third one!)
let y:String = stringA
}
再说一次,我不会宽恕这一点!!我只是展示了一些代码,其他人可能从有启发性的角度来看会觉得有趣。我确实做到了!
最佳答案
确实有一个简单的原因,它就是您列出的原因之一:“更好的安全检查”。可选绑定(bind)使编译器知道解包的范围,而程序员有责任跟踪您何时检查或未检查隐式解包的可选项是否为 nil
。
带有可选绑定(bind):
let stringA:String? = nil // (or "ABC")
if let unwrappedStringA = stringA
{
let x:String = unwrappedStringA
}
accidentallyAttemptingToUse(stringA) // Compiler error! I see my mistake.
使用隐式展开:
let stringA:String! = nil // (or "ABC")
if(stringA != nil)
{
let x:String = stringA
}
accidentallyAttemptingToUse(stringA) // Runtime crash I might find in testing. Yuck.
IUO 有哪些用途?
那么,为什么要隐式解包可选值呢?它们的存在基本上是为了一个目的:肯定会有值的属性,但要在 init
之后不久才会有,因此它们必须是可选的。通常 @IBOutlet
属于这一类:您可以相信它们有一个值,并且您不想一直打开它们,但它们不是在 init< 时分配的
,因此您必须将它们设为可选。 那就是隐式展开的可选值的用途。
展开到同名变量
您的更新暂时建议将可选项展开为具有相同名称的变量,这实际上是 优秀 Swift 风格,并且很早就被 Apple 使用并经常使用。当您解包到同名变量时,代码更容易阅读,因为您可以跟踪更少(更好)的名称。绝对接受这一点!
let stringA:String? = nil // (or "ABC")
if let stringA = stringA
{
let x:String = stringA // Of *course* this is still named `stringA`;
// it's representing the same concept, after all.
}
关于swift - 使用隐式解包选项但测试 nil 与可选绑定(bind)是否存在技术缺点?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38341198/
我不知道该怎么做... function f1() { var x = 10; function f2(fx) { var x; x = 6;
早期绑定(bind)和后期绑定(bind)有什么区别? 最佳答案 简短的回答是,早期(或静态)绑定(bind)是指编译时绑定(bind),后期(或动态)绑定(bind)是指运行时绑定(bind)(例如
如何在 SwiftUI View 上使用 Binding(get: { }, set: { }) 自定义绑定(bind)与 @Binding 属性。我已成功使用此自定义绑定(bind)与 @State
我经常发现自己遇到问题,即控件的两个(相关)值被更新,并且两者都会触发昂贵的操作,或者控件可能会暂时处于不一致的状态。 例如,考虑一个数据绑定(bind),其中两个值 (x,y) 相互减去,最终结果用
我想通过我的 ViewModel 控制我的一个窗口的高度和宽度。 这看起来很简单。 但没有。它不起作用。 它检查 ViewModel 的 Width但不是 Height . 奇怪的是,如果我切换 W
UI5中一次性绑定(bind)和单向绑定(bind)有什么区别? 是否有任何用户特定的用例我会使用它们? 我无法从文档中获得太多信息。 最佳答案 单程 它的作用:单向数据流。模型数据的变化(例如通过
(define make (lambda (x) (lambda (y) (cons x (list y))))) (let ((x 7) (p (make 4))) (cons
尽管我或多或少地了解什么是语言绑定(bind),但我很难理解它们是如何工作的。 例如,谁能解释一下如何为 WinAPI 制作 Java 绑定(bind)? 最佳答案 如果您搜索 Foreign Fun
谁能解释为什么我可以重新绑定(bind)列表但不能+? (binding [list vector] (list 1 3)) (binding [list +] (list 1 3)) (bi
我真的很喜欢 Caliburn 和命名约定绑定(bind),我很惊讶 可见性与“CanNAME”约定用于保护 Action 的方式不同。 据我所知, BooleanToVisibilityConver
我了解动态绑定(bind)的实现方式以及静态绑定(bind)和动态绑定(bind)之间的区别,但我只是无法理解动态绑定(bind)的定义。基本上它是一种运行时绑定(bind)类型。 最佳答案 基本上,
http://jsfiddle.net/3NRsd/ var foo = $("div").bind("click", function() { $("div").animate({"hei
这个问题我快疯了...我有一个用户控件,它有一个用于插入操作的 FormView 和一个用于所有其他操作的 GridView。 在这两个控件中,我都有一个 DropDownList,如下所示: '
我有一个绑定(bind)到 ListBox 的地址的 ObservableCollection。然后在 ItemTemplate 中,我使用 {Binding .} 绑定(bind)到当前地址记录。这
如果我有以下简单的 js/knockout 代码: .js( View 模型): var image = ko.observable('http://placehold.it/300x150'); 看
我正在 aurelia 上开发一个自定义属性,让用户在输入文本区域时从列表中进行选择。例如,用法将是这样的: 正如您可能注意到的,auto-complete是属性。现在,当我想显示提示时,我想在自定
我正在使用 EventEmitter2作为我的应用程序内部的消息总线。现在我需要绑定(bind)和取消绑定(bind)一些事件处理程序。因为我也希望他们bind将它们添加到给定的上下文中,我最终得到以
我有以下函数调用: $(".selector").on("click", callback.bind(this, param1, param2)); 在我的回调函数中,我想使用绑定(bind)的 th
我目前正在试验新的编译绑定(bind),并且(再次)达到了我在拼图中遗漏了一个小问题:为什么我必须调用 Bindings.Update?直到现在,我还认为实现 INotifyPropertyChang
我正在阅读一本关于编写 JavaScript 框架的书,并找到了这段代码。但是我不明白它是如何工作的,尤其是 bind.bind 的用法?有人知道吗? var bind = Function.prot
我是一名优秀的程序员,十分优秀!