Swift编程语言指南有以下示例:
class Person {
let name: String
init(name: String) { self.name = name }
var apartment: Apartment?
deinit { println("\(name) is being deinitialized") }
}
class Apartment {
let number: Int
init(number: Int) { self.number = number }
var tenant: Person?
deinit { println("Apartment #\(number) is being deinitialized") }
}
var john: Person?
var number73: Apartment?
john = Person(name: "John Appleseed")
number73 = Apartment(number: 73)
//From Apple's “The Swift Programming Language” guide (https://developer.apple.com/library/content/documentation/Swift/Conceptual/Swift_Programming_Language/AutomaticReferenceCounting.html)
Run Code Online (Sandbox Code Playgroud)
然后,当将公寓分配给该人时,他们使用感叹号来"解开实例":
john!.apartment = number73
Run Code Online (Sandbox Code Playgroud)
"打开实例"是什么意思?为什么有必要?它与仅执行以下操作有何不同:
john.apartment …Run Code Online (Sandbox Code Playgroud) 我一直在玩Swift并发现当向下投射一个要插入字典的对象时,我得到一个奇怪的警告:Treating a forced downcast to 'String' as optional will never produce 'nil'.如果我更换as,as?则警告消失.
func test() -> AnyObject! {
return "Hi!"
}
var dict = Dictionary<String,String>()
dict["test"]=test() as String
Run Code Online (Sandbox Code Playgroud)
Apple的文档说明如下
由于向下转换可能会失败,因此类型转换运算符有两种不同的形式.可选表单
as?将返回您尝试向下转换的类型的可选值.强制形式as尝试向下倾斜并强制将结果作为单个复合动作展开.
我不清楚为什么在这里使用as?而不是as正确的.一些测试显示,如果我更改test()以返回Int而不是String,如果我继续使用,代码将退出并出现错误as.如果我切换到使用as?那么代码将继续正常执行并跳过该语句(dict将保持为空).但是,我不确定为什么这是更可取的.在我看来,我宁愿程序退出并出现错误并让我知道演员表不成功然后只是忽略错误的声明并继续执行.
根据文档,我应该使用强制形式"只有当你确定转发将永远成功时".在这种情况下,我确信向下转换将永远成功,因为我知道test()只能返回一个字符串,所以我认为这是强制形式的向下转换的完美情况.那么为什么编译器会给我一个警告呢?
我最初对强行展开和隐式展开非常困惑.现在,以下理解来自我的自学:
有没有可用的隐含解包的动作,但有一些所谓的隐式解开选配.隐式解包的Optionals和普通的Optionals都是Optionals,区别在于访问一个隐式解包的Optional时,你自信地知道底层有一个有效的值并且可以使用.Normal Optionals需要if let绑定或强制unwrapping(!)动作来访问可选变量后面的可能值.
摘要:
强迫去包裹是一个行动的正常选配完成.
隐式解包的Optionals是 Optionals,通常用于类初始化,并在使用时传递没有感叹号的值.
问题:
我对吗?如果我的理解不准确,如果你纠正我,我将不胜感激.
谢谢
当我要为第二个视图解雇我的segue时,我也会发送一些像这样的值:
if let aTime = ads[indexPath.row]["unix_t"].int {
toView.time = aTime
}
if let aTitle = ads[indexPath.row]["title"].string {
toView.title = aTitle
}
Run Code Online (Sandbox Code Playgroud)
在第二个VC我宣布变量如下:
var time: Int?
var title: String?
Run Code Online (Sandbox Code Playgroud)
这就是我解开值的方式:
if time != nil {
timeLabel.text = String(time!)
}
if title != nil {
titleLabel.text = title!
}
Run Code Online (Sandbox Code Playgroud)
这一切都有效我从来没有得到任何由未包装的varibles或nil值引起的错误.但有没有更简单的方法呢?
现在感觉我检查太多了
有没有办法(通过编译器标志或脚本)检测Swift项目中的强制解包?
我正在考虑这样的事情:
let b = a as! B
let c = a!
a!.method()
Run Code Online (Sandbox Code Playgroud)
例如,不会触发误报var a: A!.
在swift文档中,您可以找到:
if convertedNumber != nil {
println("convertedNumber has an integer value of \(convertedNumber!).")
}
// prints "convertedNumber has an integer value of 123."
Run Code Online (Sandbox Code Playgroud)
有了这个解释
一旦确定可选项确实包含值,就可以通过在可选项名称的末尾添加感叹号(!)来访问其基础值.感叹号有效地说:"我知道这个选项肯定有价值; 请使用它."这被称为强制解包可选的值:
好的,明白了,但它的用处是什么?如果我没有强行拆包,那就不一样了:
if convertedNumber != nil {
println("convertedNumber has an integer value of \(convertedNumber).")
}
// prints "convertedNumber has an integer value of 123."
Run Code Online (Sandbox Code Playgroud)
感谢启发我:)
有没有一种很好的方法来访问Option Object中的Option Value?嵌套的匹配案例导致丑陋的树结构.
所以如果我有例如:
case class MyObject(value: Option[Int])
val optionObject : Option[MyObject] = Some(MyObject(Some(2))
Run Code Online (Sandbox Code Playgroud)
我知道访问该值的唯一方法是:
val defaultCase = 0 //represents the value when either of the two is None
optionObject match {
case Some(o) => o.value match {
case Some(number) => number
case None => defaultCase
}
case None => defaultCase
}
Run Code Online (Sandbox Code Playgroud)
这非常难看,因为这个构造只是用于访问一个小的Option值.
我想做的是:
optionObject.value.getOrElse(0)
Run Code Online (Sandbox Code Playgroud)
或者像你可以用Swift做的:
if (val someVal = optionObject.value) {
//if the value is something you can access it via someVal here
}
Run Code Online (Sandbox Code Playgroud)
Scala中有什么东西能让我很好地处理这些事情吗?
谢谢!
为什么不+=使用隐式解包的选项,例如:
var count: Int! = 10
count = count + 10 // This works
count += 10 // this does not work
Run Code Online (Sandbox Code Playgroud)
为什么不是可选的隐式解包,就像这样的情况count = count + 10?
我有以下代码,我试图用它来初始化变量并对其执行一些操作。
let formattedPointsValue: String?
self.formattedPointsValue = model.pointUnitsEarned.stringValueWithWhiteSpaceThousandSeperator()+" "+"model.name".localized(in: .name) ?? .none
Run Code Online (Sandbox Code Playgroud)
但是我收到警告
nil 合并运算符 '??' 的左侧 具有非可选类型“String”,因此从不使用右侧。
当我删除?? .none我的项目时,我的项目运行良好,没有问题,但是当我运行单元测试时,我收到错误
致命错误:在解包可选值时意外发现 nil
我发现解决这个问题的唯一方法是使用这段代码。
if let unformattedValue = model.pointUnitsEarned {
self.formattedPointsValue = unformattedValue.stringValueWithWhiteSpaceThousandSeperator()+" "+"model.name".localized(in: .name)
} else {
self.formattedPointsValue = nil
}
Run Code Online (Sandbox Code Playgroud)
我想了解为什么这样的事情有效:
let legend: String?
self.legend = model.pointsCategory ?? .none
Run Code Online (Sandbox Code Playgroud)
但这失败了:
let formattedPointsValue: String?
self.formattedPointsValue = model.pointUnitsEarned.stringValueWithWhiteSpaceThousandSeperator()+" "+"model.name".localized(in: .name) ?? .none
Run Code Online (Sandbox Code Playgroud) NSMetadataItemSwift下的Cocoa框架中的类包含以下函数:
func valueForAttribute(key: String!) -> AnyObject!
我还在学习强制解包和可选链接之间的区别(和细节).在上面的函数中,这是否意味着:
该key参数必须有一个值,
返回值保证有值吗?
我主要关注的是返回值后面的感叹号 - 一旦我分配了返回值:
var isDownloadedVal = item.valueForAttribute(NSMetadataUbiquitousItemIsDownloadedKey)
Run Code Online (Sandbox Code Playgroud)
我if let在检查时是否需要包含一个块,或者我保证它具有我可以安全检查的值吗?