我想比较两个对象(同一个Class)并返回NOT nil。
你如何在swift中写这样的东西? :
func returnWhatIsNotNil(objA: SomeClass, objB: SomeClass) -> SomeClass {
if objA != nil && objB != nil { //error
//both are not nil
return nil
}
if objA == nil && objB != nil { // error
// objA is nil
return objB
}
if objA != nil && objB == nil { // error
// objB is nil
return objA
}
}
有一个对象,
if let x = objA {
//objA is not nil
}
会做这个工作,但我很安静,不知道如何用两个对象做这个。
答案 0 :(得分:3)
编辑:对不起,误读了你原来的问题。如果你想要nil
两者都是非零的话,那么这里就是一个单行代码:return objA.map { objB == nil ? $0 : nil } ?? objB
。但是,@ LeoDabus使用if…let…where
的版本看起来更具可读性。
预编辑,假设你想要第一个,而不是nil:
您想使用nil-coalescing运算符??
。因此,要从函数中返回可选项,您只需要return objA ?? objB
。请注意,您的所有输入和输出类型也必须是可选的。
通常你使用它来提供一个默认值,如果是nil,即"foo".toInt() ?? 0
如果非零则展开值,或者如果它为零则用默认值替换它。
但是如果右侧也是可选的,它将返回一个可选项,如果它是非零则返回左侧,否则返回右侧,即使那个是nil。
let i: Int? = nil
let j: Int? = nil
let k: Int? = 42
if let num = i ?? j {
fatalError("won't execute")
}
if let num = j ?? k {
assert(num == 42, "k will be chosen")
}
else {
fatalError("this would run if all 3 were nil")
}
另请注意,您也可以链接??
:
let x = i ?? j ?? k ?? 0 // will result in an unwrapped 42
答案 1 :(得分:3)
class SomeObject {
}
func returnWhatIsNotNil(objA: SomeObject?, objB: SomeObject?) -> SomeObject? {
if let objA = objA where objB == nil {
return objA
}
if let objB = objB where objA == nil {
return objB
}
return nil
}
答案 2 :(得分:2)
作为@LeoDabus接受回答的后续内容,您还可以使用switch
声明:
class SomeObject {
}
func returnWhatIsNotNil(objA: SomeObject?, objB: SomeObject?) -> SomeObject? {
switch (objA, objB) {
case (let a, nil): return a
case (nil, let b): return b
default: return nil
}
}
答案 3 :(得分:1)
如上所述,可以使用零合并运算符??
。
这是你的函数的一个实现,请注意你没有定义当objA和objB都是非零时会发生什么
func returnWhatIsNotNil(objA: SomeClass?, objB: SomeClass?) -> SomeClass? {
return objA ?? objB
}
答案 4 :(得分:0)
虽然可以在Swift中对您的代码进行文字翻译,这是
func returnNotNil(num1: Int?, num2: Int?) -> Int?
{
if let x = num1 {
return x
}
else if let y = num2
{
return y
}
else
{
return nil
}
}
这里的问题是,在Swift中,我们必须将返回类型保持为可选 - 所以一旦从函数返回,你将再次检查返回值是否为nil,并且展开。 恕我直言,这是一个合乎逻辑的翻译,(假设你不介意回来,当他们都没有时)
func returnNotNilOrAssert(num1: Int?, num2: Int?) -> Int
{
if let x = num1 {
return x
}
else if let y = num2
{
return y
}
else
{
assert(false, "Both nil")
}
}
是否断言,可能是您必须要做的实现选择。另一种方法是,如果你完全确定,其中一个不是nil,你就可以制作函数的返回类型"隐式解包"。我知道当两者都是零时你想要返回nil,但是然后必须检查这个函数的返回值,它应该检查两个值并返回一个不是nil的值,恕我直言并没有多大意义,因此我试过这种方式。