. . I'm breaking bad once again asking for help--hopefully this code + any possible answers will help the community.
. . So I'm trying to make a method that allows me to safely assign optionals to the lhs, such as:
var cool_variable = risky_optional!
,
without necessarily interrupting the flow of whichever scope it's in.. the point of this is to cut down on control statements, and to not crash the program immediately on a forced unwrap (which I spend much time trying to design good code that doesn't do this naturally).
. . At first, I thought I had succeeded, because everything was working perfect... then on my fourth round of tests, I got a
Could not cast value of type 'Swift.Int' (0x105c52190) to 'Swift.String' (0x105c584d8).
. . I spent a good bit of time trying to refactor and rework, but I'm realizing that my understanding on generics, Any, and optionals just isn't concrete yet--though I do study and practice, every now and then I try to do something that just won't work.
>> 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).
. . So I see where it's hanging up, tried replacing switch with If / Guard statements, tried it with Any, Optional<>, and a couple other approaches that got nowhere... I can't get it to work, and feel that I'd just be beating my head on the keyboard at this point in my knowledge of Swift
. . I don't really need this method, (because I try to be a good designer, haha), but it's always good to save a bit of whitespace, and if I use this for most of my assignments, then should a small bug pop up later, it's possible it could correct itself (say in a while loop or update cycle) instead of crashing the program.
. . That, and even though I'm sure something with Try/Catch could work...I want to figure out why this won't run so I can learn and be a better coder.
Thanks much.
Peace and blessings! -Fluid
Actually you don't need a method for this, just do:
zazzle = str_opty ?? ""
Easy!
I don't really know why your method fails to do the job. But I think it's better to switch 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")
}
EDIT:
I now found out why your method did not work! Consider the following code
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)
Guess what it prints?
true
true
true
true
It seems like that nil
is
every optional type, no matter whether it is a struct, a class, or a protocol. If you think about this, it actually makes sense. nil
can be assigned to any optional type, right?
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With