我读到三元运算符??
如果不是nil,就打开一个可选的,但是如果我这样做:
var type: String?
type = "milk"
let certainType = type ?? "melon"
那么certainType仍然是String?
println("it's a \(certainType)")
它将打印:
it's a Optional("milk")
有什么想法?
更新:
很抱歉造成混淆-我指的是var类型:绳子?
我知道它应该打印“it 's a milk”,但我在控制台中看到的是“it' s a Optional(“milk”)”--其他人也遇到过同样的问题吗?这会不会是字符串插值引起的?
由@Antonio询问,这里有更多的上下文和真实的代码以及日志快照--类型来自Note,这是一个用于处理xcdatamodel的NSManagedObject类
class Note: NSManagedObject {
@NSManaged var type: String?
}
我在某个时候将类型设置为'todo',然后使用以下代码将它们打印出来:
println("type class:\(_stdlib_getDemangledTypeName(note.type))")
let type1 = note.type ?? "note"
println("type1:\(type1)")
let type2: String = note.type ?? "note"
println("type2:\(type2)")
而输出:
type class:Swift.Optional
type1:Optional("todo")
type2:todo
正如您所看到的,如果我不显式地将type 1的类型标记为String,它将输出不希望的结果可选(“todo”)-我在字符串插值中使用该类型来构造路径,因此它很重要
8条答案
按热度按时间qvk1mo1f1#
OPAssert代码类似于:
打印意外的字符串:
它是可选的(“milk”)
而它应该是:
“这是牛奶”
事实证明,当变量实际上是一个具有
@NSManaged
属性的属性时,就会发生这种情况。我怀疑在类型推断中有一个bug。OP声明:
打印错误的结果,而:
打印正确的一个。
因此,* 由于某种原因,在没有显式指示变量类型的情况下,nil合并运算符返回一个可选的 *。
如果我将
type
变量的类型更改为AnyObject
或AnyObject?
,它实际上会输出 * 意外 * 结果:“它是可选的(牛奶)”
我的猜测是:* 因为使用了
@NSManaged
属性,所以除非明确指示正确的型别,否则在使用时会以错误的型别(AnyObject?
)来推断属性(Property)*。至于为什么会发生这种情况,不知道(除了认为这是一个错误)
uwopmtnx2#
这是(我认为)设计好的。如果你这样做:
如果我没弄错的话,这将打印
it's a "milk"
,它在调试时比it's a String
有用得多。注意,\(...)
类似于Objective-C中的%@
:类可以重写它们的字符串表示形式。此外,正如安东尼奥已经指出的:
1.不能更改不可变变量(即
let
)。1.因此,可选的let变量是无用的(也就是说,不要执行
let type: String? = "milk"
,因为它显然永远不会为nil)。jyztefdp3#
我读到三元运算符??如果不是nil,就打开可选的,但是...
它会打开它。
字母类型:字符串?type =“milk”字母类型:
您的代码将无法编译,但如果您将let更改为var,它将工作,并且certainType将为String类型。
gg58donl4#
这就是所谓的零合并运算符。
如果您有一个Optional
a
,则当a
不是nil
时,a ?? b
的结果将是a!
,而当nil
是b
时,a ?? b
的结果将是b
。它是以下表达式的简写:因此,您正确地使用了运算子,但必须在宣告常数的同一行上初始化常数:
但是,我假设您不希望它在此上下文中成为常量(因为您要检查它是什么),因此如果使用
var
声明它,现有代码应该可以工作。64jmpszr5#
我也有类似的问题。
我有一个类型为
[String : AnyObject]
的字典,但是我查找的条目是一个String
值。我担心它可能并不总是存在。我用下面的代码检索它:但是,当条目存在时,仍然会给予字符串:
可选(实际消息)
即变量
message
的类型为String?
。我把它改成:
...现在检索到的值是一个未 Package 的非可选字符串。
gc0ot86w6#
这就是你想要的
请注意,我打开了类型。它在以下情况下有效:
因为您实际上是在向String的转换中展开。
zc0qhyus7#
在我的例子中,问题是
NSNumber?
类型的@NSManaged
属性,我试图将其 Package 在字符串中。let time = "\(nsManagedObject.optionalNsNumber ?? "") months" /// result "Optional(<random number>) months"
这个问题的解决方案是将
NSNumber
转换为stringValue
。下面是按预期工作的代码。let time = "\(nsManagedObject.optionalNsNumber.stringValue ?? "") months" /// result "<random number> months"
Swift编译器不会发现这个问题,如果你尝试使用
nil coalescing
运算符,然后将结果添加到字符串,它将指向当前的错误,Can't add NSObject and String
。将
@NSManaged
属性 Package 到字符串中时要小心。svgewumm8#
我找到一个办法试试看。