2015-06-03 50 views
1

我想比较两个对象(同一个类)并返回不为零的对象。检查两个对象在Swift中是否为零,ios xcode

你如何在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

使用写入的参数,objA和objB不能为零。在执行任何代码之前,调用会崩溃。他们必须是SomeClass类型的? – gnasher729

+0

请注意,您可以使用switch语句同时比较两个项目。我发布了一个后续接受的答案。 – vacawama

回答

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 
} 
+0

从“objA:SomeObject,objB:SomeObject”更改为“objA:SomeObject ?, objB:SomeObject?”让我与零比较。谢谢 –

+1

我添加了一个使用switch语句来完成同样事情的例子。 – vacawama

3

编辑:对不起,误解您的原始问题。如果你想nil当两者都是非零,那么这是一个单线程:return objA.map { objB == nil ? $0 : nil } ?? objB。不过,@ LeoDabus使用if…let…where的版本看起来更易读。


预编辑假设你想在第一时也不是零:

您要使用的未缴合并运算符,??。所以要从你的函数返回一个可选项,你只需要return objA ?? objB。请注意,您的所有输入和输出类型也必须是可选的。

通常情况下,您使用它来给出默认值,如果为零,即"foo".toInt() ?? 0,如果非零,则展开该值,或者将其替换为默认值(如果它为零)。

但是,如果右侧也是一个可选项,它将返回一个可选项,如果它不是零,则返回一个可选项,否则返回正确的一个,即使该项为零​​。

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 
+0

那么,你如何检查两个对象是否为零或不在一行? –

+0

'(i ?? j)== nil'如果你真的不想用'&&'来写。但是你有可能想检查_and_ unwrap,因此将它与'if let'结合使用是有用的。 –

+0

但是要从你的函数返回一个可选的,你只需要'return objA ?? objB' –

1

至于提到的零合并运算??可以使用。

这是你的函数的实现,注意你并没有确定会发生什么,当两个objA和objB是非零

func returnWhatIsNotNil(objA: SomeClass?, objB: SomeClass?) -> SomeClass? { 
    return objA ?? objB 
} 
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 
    } 
} 
+0

这是一个不错的解决方案。 – Caleb

0

虽然,一个字面翻译斯威夫特在你的代码是可能的,这是

func returnNotNil(num1: Int?, num2: Int?) -> Int? 
{ 
    if let x = num1 { 
     return x 
    } 
    else if let y = num2 
    { 
     return y 
    } 
    else 
    { 
     return nil 
    } 
} 

这里的问题是,在斯威夫特,我们将不得不继续返回类型为可选的 - 所以一旦从函数返回,你会再次必须检查返回值是不是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,当两者都是零,但然后不得不检查这个函数的返回值应该检查两个值,并返回不是零的那个,恕我直言,没有多大意义,所以我试了一下这条路。

相关问题