用于安全地将可选项分配给var的函数,或者如果为nil则赋值为default:无法将“Swift.Int”类型的值转换为“Swift.String”

时间:2016-08-23 14:07:27

标签: swift function generics optional

嘿那里!

。 。我再一次寻求帮助就是坏了 - 希望这些代码+任何可能的答案都会对社区有所帮助。

。 。所以我试图制作一个允许我安全地为lhs分配选项的方法,例如:

var cool_variable = risky_optional!

没有必要中断它所在的任何范围的流程。这一点是减少控制语句,并且不要在强制解包时立即崩溃程序(我花了很多时间试图设计好的代码,不自然地这样做。)

。 。起初,我以为我成功了,因为一切都很完美......然后在我的第四轮测试中,我得到了一个

  

无法将'Swift.Int'(0x105c52190)类型的值转换为'Swift.String'(0x105c584d8)。

。 。我花了很多时间来尝试重构和返工,但我意识到我对泛型,任何和可选项的理解并不具体 - 尽管我做的是学习和实践,但我时不时地尝试做一些不起作用的事情。

这是代码:

>> Here's a screenshot of the func, all nice and pretty in XCODE if that's your thing <<

>> And here is the implementation in XCODE <<

/** 
    Safely assign the lhs to this call--the value of $0?, or a default.
    - Don't include ? or ! in the parameter
*/
func safeAssign <ReturnType> (value_to_return: ReturnType?)
 -> ReturnType  {

    // Ensure safety
    guard value_to_return != nil 
    else {

        // Entry: found nil
        print ("SA() -> 1  : SR: $0 was nil! Can't assign to lhs")

        // -Value is irrelevant at this point
        // -switch (value_to_return) would be confusing
        let type = value_to_return

        switch ( type ) {

         case is Int?:
            print("SA() -> 2.1: assigning lhs to default Int >0<")
            return 0 as! ReturnType

         case is String?:
            print("SA() -> 2.2: assigning lhs to default String")
            return "" as! ReturnType

         default:
            // In case our switch breaks, we will know why it crashes
            print("SA() -> 2.0: No cases found--RTE incoming")

        }//switch/>

        // Should force crash, but at least I'll know exactly why
        return type!

    }//guard/>

    // Let's get out of here safely ;)
    print("SA() -> Exit: Successfully Assigned lhs to \(value_to_return!)")
    return value_to_return!

}//safeAssign/>

//---------
// Testing:
//--------

// Optional for test 1-2
var int_opty : Int? = 5

// Soon to be safe-assigned
var zizzle = 0

// Safe assign to 5
print ("\n SA Test 1:")
zizzle = safeAssign(int_opty)

// Will cause a non-safe-assignment to force unwrap nil
int_opty = nil

// Safely assign to default value, instead of unwrapping nil
print ("\n SA Test2:")
 zizzle = safeAssign(int_opty)
  print(">>>>>>>>>> Zizzle is \(zizzle)")

// Optional for test 3-4
var str_opty : String? = "five"

// Soon to be safe-assigned
var zazzle = "zero"

// Safe assign to 5
print ("\n SA Test 3:")
 zazzle = safeAssign(str_opty)

// Will cause a non-safe-assignment to force unwrap nil
str_opty = nil

// Safely assign to default value, instead of unwrapping nil
print ("\n SA Test 4:")
 zazzle = safeAssign(str_opty)
  print ("3: Zazzle is \(zazzle)")

输出:

 SA Test 1:
SR -> Exit: Successfully Assigned lhs to 5

 SA Test2:
SR -> 1  : SR: $0 was nil! Can't assign to lhs
SR -> 2.1: assigning lhs to default Int >0<
>>>>>>>>>> Zizzle is 0

 SA Test 3:
SR -> Exit: Successfully Assigned lhs to five

 SA Test 4:
SR -> 1  : SR: $0 was nil! Can't assign to lhs
SR -> 2.1: assigning lhs to default Int >0<
Could not cast value of type 'Swift.Int' (0x105c52190) to 'Swift.String' (0x105c584d8).

。 。所以我看到它挂起的地方,尝试用If / Guard语句替换switch,尝试使用Any,Optional&lt;&gt;以及其他一些无处可寻的方法...我无法让它工作,并且觉得在我对Swift的了解

中,我现在只是在键盘上敲打我的头

。 。我真的不需要这种方法,(因为我试图成为一名优秀的设计师,哈哈),但是保存一些空白总是好的,如果我在大多数作业中使用它,那么应该是一个小小的bug以后,它可能会纠正自己(比如在循环或更新周期中)而不是崩溃程序。

。 。那,即使我确定Try / Catch的某些东西可以工作......我想弄清楚为什么这个不能运行所以我可以学习并成为一个更好的编码器。

非常感谢。

和平与祝福! -Fluid

1 个答案:

答案 0 :(得分:3)

实际上你不需要一种方法,只需这样做:

zazzle = str_opty ?? ""

容易!

我真的不知道为什么你的方法不能胜任这项工作。但我觉得转换ReturnType.self

会更好
switch ReturnType.self {

case is Int.Type:
    print("SR -> 2.1: assigning lhs to default Int >0<")
    return 0 as! ReturnType

case is String.Type:
    print("SR -> 2.2: assigning lhs to default String")
    return "" as! ReturnType

default:
    // In case our switch breaks, we will know why it crashes
    print("SR -> 2.0: No cases found--RTE incoming")

}

编辑:

我现在发现了为什么你的方法不起作用!请考虑以下代码

func f<T>(x: T?) {
    print(x is Bool?)
    print(x is Int?)
    print(x is NSNumberFormatter?)
    print(x is NSURLSessionDelegate?)
}

let a: String? = nil
f(a)

猜猜它打印的是什么?

true
true
true
true

似乎每个可选类型都是nil is,无论它是结构,类还是协议。如果你想到这一点,它实际上是有道理的。可以将nil分配给任何可选类型,对吧?