Arrays containing enumerations with associated values [duplicate] - swift

This question already has an answer here:
Testing for enum value fails if one has associated value?
(1 answer)
Closed 7 years ago.
enum ConditionType {
case Normal
case Sick
case Plagued
case Poisoned(Double)
case Drunk(Double)
case Healing(Double)
case Starving
case NearDeath(Double)
case Sleepy
}
var conditions: [ConditionType]
func addCondition(condition: ConditionType) {
if conditions.contains(condition) == false {
conditions.append(condition)
}
}
In the "if conditions.contains(condition) == false {" line above I am getting the following error:
Cannot invoke 'contains' with an argument list of '(ConditionType)'. What is the deal here? If I remove the associated values from the enum elements, then it compiles just fine.
I am running XCode 7.0 Beta 3.

You need to make ConditionType equatable and crate an op== that explains whether just the types need to match for them to be the same or if the contained values also need to match.

Related

What is difference between create object with init and () in Swift [duplicate]

This question already has answers here:
In Swift, what's the difference between calling UINavigationController() vs UINavigationController.init()?
(3 answers)
Closed 5 years ago.
class A {
private var value: Int
init(value: Int) {
self.value = value
}
}
We have class A and what is the difference between I create this object by using A.init(value: 5) and A(value: 5)? Thanks
There is no functional difference between the two. Both styles will call the same initializer and produce the same value.
Most style guides that I've seen prefer to leave out the explicit .init-part in favor of the shorter A(value:) syntax — that also resembles the constructor syntax in many other languages.
That said, there are some scenarios where it's useful to be able to explicitly reference the initializer. For example:
when the type can be inferred and the act of initialization is more important than the type being initialized. Being able to call return .init(/* ... */) rather than return SomeComplicatedType(/* ... */) or let array: [SomeComplicatedType] = [.init(/* ... */), .init(/* ... */)]
when passing the initializer to a higher order function, being able to pass "something".map(String.init) rather than "something".map({ String($0) })
Again, it's a matter of style.

Swift switch statement force to write block of code [duplicate]

This question already has answers here:
Noop for Swift's Exhaustive Switch Statements
(8 answers)
Closed 5 years ago.
I have question, i have enum with 3 state. On 2 of 3 that state i want to do something, but for 3rd i do not. However, when i do not put block of code below case, compiler highligh it with red and won't allow me to run app. Example:
func leftBarButtonTappedWithType(type: CustomNavBarViewModel.LeftBarButtonType) {
switch type {
case .none:
print("")
case .back:
self.popViewController(animated: true)
case .hamburger:
self.func()
}
}
You can see that for case .none i wrote print("") because in other case i won't be able to compile. How to avoid that? Kind of ugly.
Just get your function to return in that case:
case .hamburger:
return
Hope that helps.
Per the discussion and #MartinR 's comment, break is probably a better general solution to exit the switch statement.

Swift generics and extensions need to workout [duplicate]

This question already has answers here:
Array extension to remove object by value
(15 answers)
Closed 7 years ago.
Im learning swift currently. While learning I'm stuck with generics. Im solving one simple problem that -> return index of specified element in an array
import UIKit
extension Array
{
func indexOfLetter<T:Equatable>(item:T) -> Int
{
var i = 0
for (index, value) in enumerate(self)
{
if value == item
{
return i
}
i++
}
return -1;
}
}
var arrayOfItems = ["A","B"]
arrayOfItems.indexOfLetter("A")
in this code I'm getting error that we
Can not compare two operands using == operator which are of type T.
The answer to your problem becomes more clear if we use a letter other than T for our generic identifier.
Change the method signature to use the letter U. And now we get this error message:
Binary operator '==' cannot be applied to operands of type 'T' and 'U'
This is the same error, but it's made more clear by using a different letter. The Array type is already a generic whose generic identifier is T for its type.
When we use U it unmasks the real problem.
The Equatable protocol only requires that our type defines == for comparisons to itself. We could compare two U's as long as U's type is Equatable. But the Equatable protocol does not ensure that we can compare a U to a T using ==.
This Stack Overflow answer can provide some insight on the difficulties of using the Equatable protocol with generics.

Using enum and switch case combination in Swift [duplicate]

This question already has answers here:
Switch in Swift - Case label in a switch should have at least one executable statement
(2 answers)
Noop for Swift's Exhaustive Switch Statements
(8 answers)
Closed 7 years ago.
Here is my code:
enum GameScreen
{
case kSceneFlashScreen
case kSceneMainMenu
case kSceneGameScreen
case kSceneStoreScreen
case kSceneGameOver
}
class YSGameManager: NSObject {
func replaceGameScene(inScreen: GameScreen)
{
switch inScreen
{
case GameScreen.kSceneGameScreen: //Error for here
case GameScreen.kSceneMainMenu : //here also error
}
}
}
Eror LOG: 'case' label in a 'switch' should have at least one executable statement
How to use enum in switch case in Swift ?
There's an error because you haven't got anything after : and before the next case. To solve this you can:
1. Add some code to do something.
2. Add fallthrough if you want to move to the next case. This may have been what you were trying to do. However, in Swift, switch statements don't fallthrough by default to the next case, they break.
3. Add break to stop the switch statement.
It’s complaining that you need to actually do something after the matching case. Otherwise there’s not much point matching it, and chances are it’s a typo.
Other possibly than coverage i.e. if you don’t want a default, you want to name every possible enum, even though you don’t want to do anything for some of them. In which case, stick in a break:
switch inScreen {
case kSceneGameScreen:
break
// etc.
}
Note, there’s no implicit fall through in Swift’s switch statements. You need to give one explicitly:
switch inScreen {
case kSceneGameScreen:
// do a game-screen-specific thing
fallthrough // then
case kSceneMainMenu:
// do a thing for both
// kSceneGameScreen and kSceneMainMenu
// etc.
}
But if you just want to match two possibilities, you don’t need to use fall through, you can just combine them with ,:
switch inScreen {
case kSceneGameScreen, kSceneMainMenu:
// do a thing for both
// kSceneGameScreen and kSceneMainMenu
// etc.
}

Is there a NULL statement in Swift? [duplicate]

This question already has answers here:
Noop for Swift's Exhaustive Switch Statements
(8 answers)
Closed 8 years ago.
Compiler complain about the lack of at least one executable statement on case label in a switch :
switch someData {
case .one:
// No statements
// Error occurs here
case .two:
// Some statements here
default:
// Some statements here
}
Here is the exact message:
'case' label in a 'switch' should have at least one executable statement
So is there any statement that do nothing to satisfy compiler requirement?
I know a simple statement like print() can do the job but I wonder if there is a specific one?
In other language, Ada for example there is a nullstatement to achieve this.
Set break or return, depending on what you want to do.
switch someData {
case .one:
nil
case .two:
// Some statements here
default:
// Some statements here
}