0

I am starting out with swift am trying to keep my code concise.

I have a custom init method

var title, initMainText, initBtnTitle: String?

...

init(title: String?, mainText: String?, buttonTitle: String?) {
   if let t = title {
      self.title = t
   }
   if let t = mainText {
      self.initMainText = t
   }
   if let t = buttonTitle {
      self.initBtnTitle = t
   }
   ...
}

...

Is there a more concise way to unwrap all those conditionals?

6
  • 1
    This question needs more detail. There's not really a more concise way to write this exact same logic. There are more concise ways of unwrapping multiple values, but none of them apply the exact same logic you've got here. Commented Oct 10, 2015 at 13:28
  • the answer below answers my question quite well. I wasn't aware that I could pass the optional value without doing a check. No reason for a down vote. ;) Commented Oct 10, 2015 at 13:32
  • 1
    The downvote is for asking a vague question. Commented Oct 10, 2015 at 13:34
  • There is no more detail needed. The method has optional parameters and I was under the impression I need to unwrap them. But the option of assigning them to other optional values is just as good. And I will then guard against nil when they are "used". Commented Oct 10, 2015 at 13:37
  • 1
    That self.title is an optional is a guess because your vague question doesn't include the declaration of the variable. That someone made guesses at a good answer for your question does not make your question good. Commented Oct 10, 2015 at 13:37

3 Answers 3

3

There are several solutions:

  • guard
  • multiple let/var inside the same if
  • params with default values
  • ternary conditional operator
  • Nil Coalescing Operator
  • Don't accept optional params in the init (as suggested by nhgrif)

Looking at your example it seems that

  • self.title
  • self.initMainText
  • self.initBtnTitle

are optionals so you could simply write:

init(title: String?, mainText: String?, buttonTitle: String?) {
   self.title = title
   self.initMainText = mainText
   self.initBtnTitle = buttonTitle
   ...
}
Sign up to request clarification or add additional context in comments.

3 Comments

Only right answer. You missed one solution though (which would be my first recommendation): don't accept optionals. Change the signature to init(title: String, mainText: String, buttonTitle: String)
As @nhgrif was fond of pointing out, this isn't the same logic. You are overwriting a potential default value with nil when nils are sent to the initializer.
Look how the properties are defined in the original question. They don't have a default value so there is nothing to overwrite.
1

This is slightly different logic that yours. If you'd like to assign a default value to the properties when nil is sent into the initializer, then this would be a good place for the nil coalescing operator:

init(title: String?, mainText: String?, buttonTitle: String?) {
   self.title = title ?? ""
   self.initMainText = mainText ?? ""
   self.initBtnTitle = buttonTitle ?? ""
   ...
}

Now that it is clear that your properties are optionals, the following has the same logic as yours: it will change the value of the property if the new value is not nil:

class Foo {
    var title: String? = "possible default value"
    var initMainText: String? = "possible default value"
    var initBtnTitle: String? = "possible default value"

    init(title: String?, mainText: String?, buttonTitle: String?) {
        self.title = title ?? self.title
        self.initMainText = mainText ?? self.initMainText
        self.initBtnTitle = buttonTitle ?? self.initBtnTitle
    }
}

7 Comments

This is different logic. Realistically, you want self.title = title ?? self.title
This is an initializer, so self.title has no value yet.
@vacawama: Actually self.title could already have a value if declared with a default value.
@vacawama: 1) With my comment I mean that with self.title = title ?? "" you are losing the default value of self.title. 2) The code actually works: class Bob { var title = "Bob" init(name: String?) { self.title = title ?? self.title } }
I see what you're saying. In that case I would suggest class Bob { var title init(name: String?) { self.title = title ?? "Bob" }. Doing it your way has merit though if you have several initializers.
|
0

You can write in single statement with comma seprated if or guard. But in this case if title and mainText should be non nil. It is different logic but this is one way to define multiple condition in single line. If you want other wise than you should refer @vacawama answer

var title: String? = "title"
var mainText: String? = "maintest"

if let title = title, mainText = mainText {
    self.initMainText = title
    self.initBtnTitle = mainText
}

1 Comment

This is a different logic, infact if only title (or mainText) is populated then the if body is not executed.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.