Skip to main content

[From C# to Swift] 02. Basic Operators

Terminology
#

1. Core Concepts
#

  • Explanation: Swift operators are categorized as Unary, Binary, and Ternary. These concepts are identical to most members of the C language family. The objects being operated on are called Operands.
  • Key Syntax: Unary (-a), Binary (a + b), Ternary (a ? b : c)

2. Example
#

let i = 1 + 2
if enteredDoorCode && passedRetinaScan { ... }

Logic Breakdown: + is a binary operator that adds 1 and 2. && is a logical AND operator used to combine two boolean values.

3. C#
#

Concept Mapping: C# also possesses these three categories of operators; the fundamental classification is identical.

C# Example:

int i = 1 + 2;
if (enteredDoorCode && passedRetinaScan) { ... }

Key Differences:

  • Syntax: Basically identical.

Assignment Operator
#

1. Core Concepts
#

  • Explanation: Uses = to initialize or update the variable on the left with the value on the right. Swift’s assignment operator has a crucial safety feature: it does not return a value.
  • Key Syntax: =
  • Note:

If the right side of the assignment operator is a Tuple with multiple values, its elements can be decomposed into multiple constants or variables at once.

2. Example
#

let b = 10
var a = 5
a = b
// a is now equal to 10

var (x, y) = (1, 2)
// x is equal to 1, y is equal to 2

if x = y {
    // This is invalid, because x = y does not return a value
}

Logic Breakdown: This code demonstrates basic assignment and Tuple decomposition assignment. Most importantly, the last part shows that the Swift compiler will report an error, preventing the common mistake where a developer intends to write == (comparison) but accidentally writes = (assignment).

3. C#
#

Concept Mapping: Corresponds to = assignment in C#. However, assignment expressions in C# do return a value (the value being assigned).

C# Example:

int b = 10;
int a = 5;
a = b;

// C# 7.0+ supports Tuple deconstruction
(int x, int y) = (1, 2);

// In C#, this is legal in certain cases (though the compiler might warn, or within a while loop)
// if (x = y) { ... } // If x, y are bool, this compiles

Key Differences:

  • Syntax: Tuple deconstruction syntax let (x, y) = (1, 2) is very concise, similar to C#’s (var x, var y) = (1, 2).
  • Behavior: Trap Warning! In C#, the result of the expression a = b is the value of b, allowing chained assignments like a = b = c. However, in Swift, assignment does not return a value, so a = b = c is illegal, and if x = y results in a compilation error. This is a design choice to prevent bugs.

Arithmetic Operators
#

1. Core Concepts
#

  • Explanation: Swift supports standard arithmetic operations (+, -, *, /). Unlike C/C++, Swift allows no value overflow by default. If a calculation result exceeds the type’s range, the program will report an error (Crash) instead of silently truncating.
  • Key Syntax: +, -, *, /, String concatenation
  • Note:

Unlike arithmetic operators in C and Objective-C, Swift arithmetic operators do not allow values to overflow by default. You can opt in to overflow behavior by using Swift’s overflow operators (such as &+).

2. Example
#

1 + 2       // Equals 3
5 - 3       // Equals 2
2 * 3       // Equals 6
10.0 / 2.5  // Equals 4.0
"hello, " + "world"  // Equals "hello, world"

Logic Breakdown: Demonstrates basic operations for integers and floating-point numbers, as well as using + for string concatenation.

3. C#
#

Concept Mapping: Corresponds to C# arithmetic operators.

C# Example:

int sum = 1 + 2;
double div = 10.0 / 2.5;
string str = "hello, " + "world";

Key Differences:

  • Syntax: Completely identical.
  • Behavior: Memory Management and Safety. C# int operations in a default unchecked context will overflow (Wrap around), unless you explicitly place them in a checked block. Swift is effectively checked by default; overflow causes a Runtime Error. To allow overflow like the C# default, Swift requires the use of overflow operators like &+, &-, &*.

Remainder Operator
#

1. Core Concepts
#

  • Explanation: Calculates a % b, determining how many multiples of b fit inside a and returning the remaining part.
  • Key Syntax: %
  • Note:

The remainder operator (%) is also known as the modulo operator in other languages. However, strictly speaking, Swift’s behavior regarding negative numbers makes it a “remainder” rather than “modulo” operation.

2. Example
#

9 % 4    // Equals 1
-9 % 4   // Equals -1

Logic Breakdown: 9 = (4 x 2) + 1, so the remainder is 1. -9 = (4 x -2) + (-1), so the remainder is -1. The rule in Swift is that the sign of a % b matches the sign of a.

3. C#
#

Concept Mapping: The % operator in C# is also a Remainder Operator, not mathematical Modulo.

C# Example:

int r1 = 9 % 4;   // 1
int r2 = -9 % 4;  // -1

Key Differences:

  • Behavior: Swift and C# behave identically here. Both return the remainder for negative numbers (the sign of the result follows the dividend).

Unary Minus / Plus Operator
#

1. Core Concepts
#

  • Explanation: - toggles the sign of a numeric value; + returns the value itself (usually exists for symmetry).
  • Key Syntax: -, +

2. Example
#

let three = 3
let minusThree = -three       // -3
let plusThree = -minusThree   // 3
let minusSix = -6
let alsoMinusSix = +minusSix  // -6

Logic Breakdown: Directly manipulates the numeric sign.

3. C#
#

Concept Mapping: Fully corresponds to C# unary operators.

C# Example:

int three = 3;
int minusThree = -three;

Key Differences:

  • Behavior: No difference.

Compound Assignment Operators
#

1. Core Concepts
#

  • Explanation: Combines an operation with assignment, such as +=.
  • Key Syntax: +=, -=, *=, /=
  • Note:

Compound assignment operators do not return a value. For example, you cannot write let b = a += 2.

2. Example
#

var a = 1
a += 2
// a is now 3

Logic Breakdown: a += 2 is equivalent to a = a + 2.

3. C#
#

Concept Mapping: C# also has +=.

C# Example:

int a = 1;
a += 2;
// int b = (a += 2); // This is legal in C#!

Key Differences:

  • Behavior: Re-emphasizing that Swift’s += does not return a value, whereas C#’s += returns the result of the operation. Therefore, in Swift, you cannot use it as part of a larger expression like you can in C#.

Comparison Operators
#

1. Core Concepts
#

  • Explanation: Used to compare two values, returning a Bool (true or false). Swift supports Tuple comparison (for Tuples with fewer than 7 elements).
  • Key Syntax: ==, !=, >, <, >=, <=, ===, !==
  • Note:

Swift also provides two identity operators (=== and !==) to test whether two object references point to the same object instance. The Swift standard library includes tuple comparison operators for tuples with fewer than 7 elements.

2. Example
#

1 == 1   // true
(1, "zebra") < (2, "apple")   // true (because 1 < 2)
(3, "apple") < (3, "bird")    // true (3 equals 3, and apple is less than bird)

Logic Breakdown: Tuple comparison is performed “left to right”. Once an element is found to be unequal, the comparison result of that element determines the result for the entire Tuple.

3. C#
#

Concept Mapping: C# comparison operators. === corresponds to Object.ReferenceEquals in C#.

C# Example:

bool result = 1 == 1;
// C# 7.3+ supports Tuple `==` and `!=`, but `<` `>` do not directly support Tuple comparison
var t1 = (1, "zebra");
var t2 = (2, "apple");
// bool tupleComp = t1 < t2; // Compile error, C# Tuple does not directly support <

Key Differences:

  • Syntax: Swift’s === used for Reference Type pointer comparison is more concise than C#’s Object.ReferenceEquals(a, b).
  • Behavior: Swift natively supports Tuple magnitude comparison (<, >). C# Tuples (ValueTuple) currently only support == and !=. To compare magnitude, one must call CompareTo or write custom comparison logic.

Ternary Conditional Operator
#

1. Core Concepts
#

  • Explanation: question ? answer1 : answer2. If question is true, it returns answer1; otherwise, it returns answer2.
  • Key Syntax: ? :

2. Example
#

let contentHeight = 40
let hasHeader = true
let rowHeight = contentHeight + (hasHeader ? 50 : 20)
// rowHeight equals 90

Logic Breakdown: This is a concise if-else expression, suitable for single-line assignments.

3. C#
#

Concept Mapping: Fully corresponds to the ? : operator in C#.

C# Example:

int contentHeight = 40;
bool hasHeader = true;
int rowHeight = contentHeight + (hasHeader ? 50 : 20);

Key Differences:

  • Behavior: No difference.

Nil-Coalescing Operator
#

1. Core Concepts
#

  • Explanation: a ?? b. If the Optional a has a value, it unwraps and uses it; if it is nil, it uses the default value b.
  • Key Syntax: ??
  • Note:

If a is not nil, b is not evaluated. This is known as short-circuit evaluation.

2. Example
#

let defaultColorName = "red"
var userDefinedColorName: String?   // Defaults to nil
var colorNameToUse = userDefinedColorName ?? defaultColorName
// colorNameToUse is set to "red"

Logic Breakdown: This is a very elegant way to handle Optionals, avoiding verbose if let blocks or ternary operators.

3. C#
#

Concept Mapping: Corresponds to the Null-coalescing operator ?? in C#.

C# Example:

string defaultColor = "red";
string? userColor = null;
string colorToUse = userColor ?? defaultColor;

Key Differences:

  • Syntax: Completely identical. Swift targets Optional types, while C# targets Nullable Reference Types or Nullable Value Types.

Range Operators
#

1. Core Concepts
#

  • Explanation: Swift provides specific operators to express ranges of values.
    • Closed Range a...b: Includes both a and b.
    • Half-Open Range a..<b: Includes a but excludes b.
    • One-Sided Ranges a... or ...b: Extends as far as possible in one direction.
  • Key Syntax: ..., ..<

2. Example
#

// Closed Range
for index in 1...5 { ... } // 1, 2, 3, 4, 5

// Half-Open Range
for i in 0..<count { ... } // 0 to count-1

// One-Sided Range (used for array slicing)
for name in names[2...] { ... } // From index 2 to the end

Logic Breakdown: Closed ranges are often used for loops where all values are needed; Half-open ranges are particularly suitable for traversing 0-based array indices.

3. C#
#

Concept Mapping: C# 8.0 introduced the Range syntax ...

C# Example:

// C# Range is mainly used for indexing and slicing, rarely directly in foreach loops (requires Enumerable.Range)
string[] names = { "A", "B", "C", "D" };

// Swift: names[2...]
var slice = names[2..]; 

// Swift: 1...5 (C# has no direct loop syntax for this, usually uses for loop)
// foreach (var i in 1..5) // C# does not support this syntax
foreach (var i in Enumerable.Range(1, 5)) { ... } 

Key Differences:

  • Syntax:
    • Swift’s closed range is ..., C#’s Range is ...
    • Swift’s half-open range is ..<, whereas C#’s .. is inherently half-open (Exclusive end).
  • Behavior: Swift’s Range is a core type (ClosedRange<T>, Range<T>) that can be directly used in for-in loops, switch pattern matching (case 1...10:), and array slicing. C#’s Range (System.Range) is currently mainly used for array/Span slicing indices and cannot be directly iterated over in a foreach loop.

Logical Operators
#

1. Core Concepts
#

  • Explanation: Combines boolean logic values.
  • Key Syntax: !a (NOT), a && b (AND), a || b (OR)
  • Note:

Swift logical operators && and || are left-associative.

2. Example
#

if !allowedEntry { ... }
if enteredDoorCode && passedRetinaScan { ... }
if hasDoorKey || knowsOverridePassword { ... }

Logic Breakdown: Supports short-circuit evaluation, meaning if the left side of && is false, the right side is not evaluated; if the left side of || is true, the right side is not evaluated.

3. C#
#

Concept Mapping: Fully corresponds to C# logical operators.

C# Example:

if (!allowedEntry) { ... }
if (enteredDoorCode && passedRetinaScan) { ... }

Key Differences:

  • Behavior: No difference. Both support short-circuit evaluation. It is worth noting that Swift encourages the use of parentheses () to clarify the precedence of complex expressions, which is also a good habit in C#.