The Apple documentation says
Every switch statement must be exhaustive. That is, every possible
value of the type being considered must be matched by one of the
switch cases.
So in new Xcode I have placed a code like this
println(UInt16.min); // Output : '0'
println(UInt16.max); // Output : '65535'
var quantity : UInt16 = 10;
switch quantity {
case 0...65535: //OR case UInt16.min...UInt16.max:
println();
default:
println();
}
Now if i remove the default section I get a compiler error:
Switch must be exhaustive
Do you want to add missing cases? Fix
So my question is for a case that I have mentioned as case 0...65535: have I not mentioned all the case values for an UInt16 ?? But still I am getting an error ?? Why am I getting this error, Did i miss something ??
Swift only truly verifies that a switch block is exhaustive when working with enum types. Even a switching on Bool requires a default block in addition to true and false:
var b = true
switch b {
case true: println("true")
case false: println("false")
}
// error: switch must be exhaustive, consider adding a default clause
With an enum, however, the compiler is happy to only look at the two cases:
enum MyBool {
case True
case False
}
var b = MyBool.True
switch b {
case .True: println("true")
case .False: println("false")
}
If you need to include a default block for the compiler's sake but don't have anything for it to do, the break keyword comes in handy:
var b = true
switch b {
case true: println("true")
case false: println("false")
default: break
}
Part of why you see that error because the compiler can't verify that switch is exhaustive without running code. The expression 0...65535 creates a ClosedInterval struct, and when the switch statement executes it has to ask that struct if the value quantity is in the interval. There's room for that to change at run time, so the compiler can't check it at compile time. (See the Halting Problem.)
More generally, the compiler can't detect an exhaustive switch for integer values — even if you add specific cases for every integer value (case 0: ... case 1: ... ... case 65535:), it doesn't know your switch is exhaustive. (Theoretically it could, though: consider filing a feature request about this if it's something you'd like to see.)
As it stands, there are two scenarios where Swift can detect completeness and allow you to omit the default clause: enums and value binding in tuples. #NateCook's answer covers enums — if you switch on an enum value and have a case in your switch for every case in the enum, you don't need a default. You also don't need a default label if you switch on a tuple and bind every possible combination of values, as seen in the Swift book:
switch anotherPoint {
case (let x, 0):
println("on the x-axis with an x value of \(x)")
case (0, let y):
println("on the y-axis with a y value of \(y)")
case let (x, y):
println("somewhere else at (\(x), \(y))")
}
You might generalize this rule as "if the type system knows about the possible values of your type, it can detect switch completeness", but the fact that there's a level on which the type system doesn't know the range of possible (e.g.) UInt32 values is sort of splitting hairs...
Swift 4.1. Either you need to specify all cases or Just include default block inside switch statement.
(As of Swift 4.2, and probably earlier): I have a helper function that converts a Bool? into the selectedSegmentIndex for a UISegmentedControl with 2 segments. If the value is nil then neither segment should be selected. My function uses a switch, which returns the appropriate segment index for true or false values, and uses this to explicitly test for the nil and satisfy the compiler's need for it to be exhaustive:
case nil: // only remaining possible value
fallthrough
default:
return UISegmentedControl.noSegment
Technically, the case nil: fallthrough isn't required because the default: will suffice, but this syntax may be useful if you want to explicitly test a value to make the code more self-documenting, or perhaps in another situation.
Check if your enum was initialised as an optional which could be either case or nil
Related
I am expecting the code below to cover the full Float range of which I use only a very small part just above 0.
My app however sometimes crashes in the field because it hits default: fatalError().
What could possibly be wrong here?
var value: Float // Between a little above 0 and about 15.
...
switch value
{
case ...3: return 0
case 3...10: return 1
case 10...: return 2
default: fatalError()
}
This switch will fall all the way through default for example if value is Float.nan or Float.signalingNaN, so it's technically possible for the app to legitimately crash at that point.
Consider adding some logging before crashing to check which value causes it to crash.
You have covered all cases except for the values whose eight exponent bits are all 1s. None of these are "Between a little above 0 and about 15", so your assumption is currently incorrect.
https://en.wikipedia.org/wiki/Single-precision_floating-point_format#Exponent_encoding
Let's write a simple class to explain in my head :
class SomeClass {
var happyToUsed = 10
}
And create an object
let someObject = SomeClass()
and use its property for case 1:
someObject.happyToUsed // prints 10
for case 2:
someObject.self.happyToUsed // prints 10
and case 3
someObject.self.self.self.self.happyToUsed // prints 10 compiler is still ok, even if self count 1k
I know case 1 and case 2 is same ( directly point the same object ). Even if I have used SomeClass.self rather than objects cases will act the same way. I ever used case 3 in a project so far.
My question is there any example case 3 which I should prefer or negative effect on memory management?
This is a Postfix Self Expression according to the Swift reference:
A postfix self expression consists of an expression or the name of a type, immediately followed by .self
The first form evaluates to the value of the expression. For example, x.self evaluates to x.
The fact that you can write .self indefinitely is just a side effect of this definition. Since x.self is an expression itself, you can add .self to it too. And you can do this forever.
That doesn't mean you should though.
These do the same thing:
let x = 10
let x = 10
Hopefully you'd agree that the second one reads better. Similarly, .self is generally redundant. According to this discussion, it seems like .self is really just a legacy from Objective-C. IMO it also makes syntaxes like the identity key path (\.self) "make more sense".
There are no differences between them, ultimately you are pointing to the same instance; Classes are reference types so whatever happens, it will always point to the same reference; You don't need to repeat it as it takes the same location in the memory which is already reserved.
Hope Dart devs will add range of values and range checking in switch/case operators -
check if value is in range, check array elements, check multiple variables with same switch operator:
int i=27;
switch (i) {
case 1..30:
break;
default:
}
List<int> a=[1,5,7,14,25,30];
switch (a) {
case a.contains(5):
break;
case a[1..4]>0:
break;
}
switch ([a,i]) {
case i==5:
case a[1..4]>0:
break;
case a[i] is int:
break;
}
You're asking for something akin to pattern matching in C#. This isn't the place to be posting about your hopes for Dart's future. StackOverflow is a place to post issues you're having so that other people can help with specific answers.
That said, here's the situation. The Dart team has a lot on their plate for their roadmap across the various upcoming versions of Dart, and though I haven't looked through every post, I didn't see pattern matching among them. And if I'm to be perfectly honest here, I'd agree that pattern matching isn't nearly high enough a priority for them to focus on it at the expense of other features like, for instance, bringing nullable variables to full release.
If I were in the Dart team's shoes and I saw this proposal, I would ask how this feature benefits the language. What problems or inadequacies exist in the language that would be solved by pattern matching? Just about any application of a switch block with pattern matching could also be done with a series of if blocks:
Switch with pattern matching:
dynamic obj;
switch (obj) {
case obj == null:
print('obj is null');
break;
case obj is List:
print('length of obj is ${obj.length}');
break;
case obj is num && obj >= 5:
print('obj is greater than 5');
break;
default:
print('obj didn't match any conditions');
break;
}
If blocks:
dynamic obj;
if (obj == null) {
print('obj is null');
} else if (obj is List) {
print('length of obj is ${obj.length}');
} else if (obj is num && obj >= 5) {
print('obj is greater than 5');
} else {
print('obj didn't match any conditions');
}
(To put an even finer point on it, the if block approach results in fewer lines. What's more, the switch block requires a fair amount of boilerplate since each case or default requires a break statement.)
What's more, there isn't going to be any performance benefit, either. A switch block typically works like a hash table, reaching the desired code in O(1) constant time. However, this isn't possible with pattern matching, so in order to support this, languages with pattern matching support tend to pre-compile the match statement into something else entirely, thus losing the performance benefit of the hash table. This is evident in C# where pattern matching in a switch block is merely syntactic sugar for the equivalent set of if statements. (I'm not going to paste an example of it here because A] it's beside the point and B] it's too long, so you're going to have to trust me on this.)
So yeah, the only benefit to having this feature would be some subjective readability, and that's not nearly enough to justify it being a top priority addition to the language.
Now that being said, this is something that has been discussed here, here, and here. Pattern matching could have some usefulness when paired with other language features, such as first-class tuples and object destructuring. Unfortunately, Dart doesn't have many of those features either, and if we're talking about which features would benefit more, I would definitely rather have those features first.
TL;DR - Probably not any time soon.
I have 2 signal producer like this
func textSignal() -> SignalProducer(String?,NoError)
and
func searchSignal(text:String) -> SignalProducer([User]?,NSError)
how to call searchSignal without nested function? since flatmap & attemptMap need the same error result like this case is NoError and NSError
There are 2 type differences that one must fix to be able to compose both functions.
The original signal can carry nils, and the function you're trying to flatMap it with doesn't accept nils. The type system is telling you that you need to choose a policy as to what to do in those cases. Some options:
Filter nils:
textSignal.filter { $0 != nil }.map { $0! }
Not recommended because you'll ignore those values, so if the user searches for "foo", and then the text field produces a nil string, the app would still show the search results for "foo".
Make the search function allow nils: this would be easy to do, but you're really just shifting the problem over to the other function, which would have to handle the nil values.
Treat nil strings as empty strings
textSignal.map { $0 ?? "" }
This is probably the simplest and the one that produces the most natural results.
The second difference is the error type. The original signal doesn't produce errors, but the second one can. Using the promoteErrors function we can turn the first function from NoError to NSError like this:
textSignal.promoteErrors(NSError)
This is safe to do with NoError signals because we know at compile time that they won't actually produce errors, and therefore no casting needs to happen to change it to NSError.
Should I return a optional value like:
func someFunc(#num: Int) -> Obj? {
if num < 0 {
return nil
}
...
}
Or just use assert:
func someFunc(#num: Int) -> Obj {
assert(num >= 0, "Number should greater or equal then zero")
...
}
Edit: Now the conditions are identical in two cases, the number should greater or equal then 0. Negative values are not permitted.
If you use assert and the caller passes an invalid argument it is a non-recoverable error/crash. The caller may not be aware of all the ways the assert may be caused, that is internal logic the caller is not supposed to know.
Really the only time assert is meaningful is to check the calling arguments on method entry and even in that case it must be made clear to the user exactly what is invalid and that can never be made more stringent for the life of the method.
Since this is about Swift returning an Optional seems to make the most sense and it will be clear to the caller that a possible error must be handled. Optionals are a major feature of Swift, use them.
Or always return a useful result the way atan() handles being called with ±0 and ±Inf.
It depends on what you want the precondition of the function to be: if it is an error call it with a negative value (or non-positive; your two examples are contradictory), then go with the assert and document this. Then it becomes part of the contract that the user of the function must check the value if it's uncertain. Or if it makes more sense to support these values and return nil (e.g., the function will typically be called with such values and the nil is not an issue for that typical use), do that instead… Without knowing the details it's impossible to tell which suits best, but my guess would be the former.