? Operator in Swift

What is the ?? operator?

Nil-Coalescing Operator (??)

The nil-coalescing operator (a ?? b) unwraps an optional a if it contains a value, or returns a default value b if a is nil. The expression a is always of an optional type. The expression b must match the type that is stored inside a.

?? - indicates default value assignment, when your variable has a nil value.

Consider following example:

var int a = nil    // var a with nil value assignment

var int b = a ?? 1 // first trying to get value from a. If var a has nil then it will try assign value 1.

print("b = \(b)")

result: b = 1

?? operator in Swift

It is "nil coalescing operator" (also called "default operator"). a ?? b is value of a (i.e. a!), unless a is nil, in which case it yields b. I.e. if favouriteSnacks[person] is missing, return assign "Candy Bar" in its stead.

What does the ?= operator do in Swift?

This question is a quite interesting topic in Swift language.

In other programming languages, it is closed to operator overloading whereas in Swifty terms, it is called Custom Operators. Swift has his own standard operator, but we can add additional operator too. Swift has 4 types of operators, among them, first 3 are available to use with custom operators:

  • Infix: Used between two values, like the addition operator (e.g. 1 + 2)
  • Prefix: Added before a value, like the negative operator (e.g. -3).
  • Postfix: Added after a value, like the force-unwrap operator (e.g. objectNil!)
  • Ternary: Two symbols inserted between three values.

Custom operators can begin with one of the ASCII characters /, =, -, +, !, *, %, <, >, &, |, ^, ?, or ~, or one of the Unicode characters.

New operators are declared at a global level using the operator keyword, and are marked with the prefix, infix or postfix modifiers:

Here is a sample example in the playground[Swift 4].

 infix operator ?=

func ?= (base: inout String, with: String)
{
base = base + " " + with
}

var str = "Stack"
str ?= "Overflow"
print(str)

Output:

Stack Overflow

Please check the topic name Advanced operator in apple doc.

What do the & and | operators do? How are they different from && and ||? Swift

See the Wikipedia page on Bitwise Operation and the Swift documentation for bitwise operators.

These are bitwise operators. & is bitwise AND and | is bitwise OR.

See these examples:

    0011 (decimal 3)
AND 0010 (decimal 2)
= 0010 (decimal 2)

0101 (decimal 5)
OR 0011 (decimal 3)
= 0111 (decimal 7)

Source: Wikipedia

The uses of bitwise operators have been discussed before on StackOverflow:

  • practical applications of bitwise operations
  • Using bitwise operations

A use of bitwise XOR (not in your question, but a cool logic gate anyway) that caught my eye (by @Vilx- here) (I don't know how it works, but the answer was accepted and up-voted 34 times)

EDIT: If you want to know how it works, there's a nice simple proof over on XOR swap algorithm - Wikipedia

Swapping two integer variables without an intermediary variable:

A = A^B // A is now XOR of A and B
B = A^B // B is now the original A
A = A^B // A is now the original B

If these don't help, the Wikipedia page I already linked to twice in this post has an Applications section, but they don't really apply to higher-level languages (unless for some reason you want to optimize your arithmetic to use only bitwise operations).

Memory safety of “+=” operator in Swift

I know you've got it, but a clarification for future readers; in your comments, you said:

... it is, in the end, a problem with any one-line code changing self by reading self first.

No, that alone is not sufficient. As the Memory Safety chapter says, this problem manifests itself only when:

  • At least one is a write access.
  • They access the same location in memory.
  • Their durations overlap.

Consider:

var foo = 41
foo = foo + 1

The foo = foo + 1 is not a problem (nor would foo += 1; nor would foo += foo) because constitutes a series of "instantaneous" accesses. So although we have (to use your phrase) "code changing self by reading self first", it is not a problem because their durations do not overlap.

The problem only manifests itself when you're dealing with "long-term" accesses. As that guide goes on to say:

A function has long-term write access to all of its in-out parameters. The write access for an in-out parameter starts after all of the non-in-out parameters have been evaluated and lasts for the entire duration of that function call. If there are multiple in-out parameters, the write accesses start in the same order as the parameters appear.

One consequence of this long-term write access is that you can’t access the original variable that was passed as in-out, even if scoping rules and access control would otherwise permit it—any access to the original creates a conflict.

So, consider your second example:

var stepSize = 1
func incrementInPlace(_ number: inout Int) {
number += stepSize
}
incrementInPlace(&stepSize)

In this case, you have a long-term access to whatever number references. When you invoke it with &stepSize, that means you have a long-term access to the memory associated with stepSize and thus number += stepSize means that you're trying to access stepSize while you already have a long-term access to it.

~= operator in Swift

It is an operator used for pattern matching in a case statement.

You can take a look here to know how you can use and leverage it providing your own implementation:

  • http://oleb.net/blog/2015/09/swift-pattern-matching/
  • http://austinzheng.com/2014/12/17/custom-pattern-matching/

Here is a simple example of defining a custom one and using it:

struct Person {
let name : String
}

// Function that should return true if value matches against pattern
func ~=(pattern: String, value: Person) -> Bool {
return value.name == pattern
}

let p = Person(name: "Alessandro")

switch p {
// This will call our custom ~= implementation, all done through type inference
case "Alessandro":
print("Hey it's me!")
default:
print("Not me")
}
// Output: "Hey it's me!"

if case "Alessandro" = p {
print("It's still me!")
}
// Output: "It's still me!"

Swift - How to overload += for Int to pass the operator as a parameter in a function call like nextPage(page: pageIndex += 1)?

Your code is close, but it needs to do two things:

  1. Add the right hand side to the left hand side
  2. Return the new value.

Your code only returns the new value, it does not update the left hand side value. In theory, you could use this:

func += (lhs: inout Int, rhs: Int) -> Int {
lhs = lhs + rhs
return lhs
}

But there is another problem; The standard += operator has a void return type and you have defined a new operator with an Int return type.

If you try and use the += operator in a context where a void return type is acceptable (which is the normal use of this operator) the compiler will give an ambiguity error, since it can't determine which function it should use:

someIndex += 1   // This will give an ambiguity compile time error

You can address this by defining the operator using generics, where the arguments conform to AdditiveArithmetic (Thanks to @NewDev for this tip)
:

func += (lhs: inout T, rhs: T) -> T {
lhs = lhs + rhs
return lhs
}

I must say, however, that this does seem like quite a lot of complexity to add, when you could simply have two lines of code; one to increment the pageIndex and then a call to the function.

How to set UIButton title using ternary operator in swift

You need to check against a Bool, not a string. If you add a variable to hold the state then you can do it with

class LoginVC: UIViewController{

@IBOutlet weak var changeOtpBtn: UIButton!
var shouldLoginWithEmail = false


override func viewDidLoad() {
super.viewDidLoad()

self.changeOtpBtn.setTitle(shouldLoginWithEmail ? "Login with Email" : "AELogin with phoneD", for: .normal)
}

If you want to see a larger example, Try this in a playground:

import UIKit
import PlaygroundSupport

class MyViewController : UIViewController {
var shouldLoginWithEmail = false

lazy var button: UIButton = {
UIButton()
}()

@objc func buttonClicked() {
print("tapped")
shouldLoginWithEmail.toggle()
setLoginButtonTitle()
}

func setLoginButtonTitle() {
button.setTitle(shouldLoginWithEmail ?
"Login with Email" :
"AELogin with phoneD",
for: .normal)
}


override func loadView() {
let view = UIView()
view.backgroundColor = .white

button.addTarget(self, action: #selector(buttonClicked),
for: .touchUpInside)
button.frame = CGRect(x: 100, y: 200, width: 200, height: 20)
button.setTitleColor(.blue, for: .normal)
setLoginButtonTitle()

view.addSubview(button)
self.view = view
}
}
// Present the view controller in the Live View window
PlaygroundPage.current.liveView = MyViewController()

Which shows the changing button title.

Sample Image

You should be able to get what you need from here.

While loop with double conditional and || logical operator in Swift

You just need to break loop

while S < 10  {
S += 1
let D = Int.random(in: 0...24)
if D == 0 {
print("D = 0 in a cycle \(S)/10")
break
}
}


Related Topics



Leave a reply



Submit