Interview - 10 questions about Swift. Part 2

Original author: Animesh Mishra
  • Transfer
There is less and less time left until the launch of the “iOS Developer” course , so today we continue to publish material from the “10 Questions about Swift” series. The first part of which can be read here .



Explain generics in Swift?


Generics (generic templates) allow you to write flexible, reusable functions and types that can work with any type. You can write code that avoids duplication and expresses its purpose in a clear, abstract manner.

The Array and Dictionary types in Swift are universal collections (generics).
In the code below, a universal function for swap two values ​​is used for a string and an integer. This is an example of reusable code.

func swapTwoValues(_ a: inout T, _ b: inout T) {
 let temporaryA = a
 a = b
 b = temporaryA
}
var num1 = 4
var num2 = 5
var str1 = “a”
var str2 = “b”
swapTwoValues(&num1,&num2)
swapTwoValues(&str1,&str2)
print (“num1:”, num1) //output: 5
print (“num2:”, num2) //output: 4
print (“str1:”, str1) //output: b
print (“str2:”, str2) //output: a

What are optional types in swift and when should they be used?


Optional (Optional, “optional”) in Swift is the type in which the value may or may not be. Options are indicated by adding “?” To any type.

Options for using the optional:

  1. Code snippets that may fail (I expected something, but received nothing).
  2. Objects that are currently empty but may become something later (and vice versa).

A good example of an optional: A

property that may or may not be present , such as a middle name or husband / wife in the Person class.

A method that can return either a value or nothing , for example, matching in an array.

A method that can return either a result or an error and return nothing , for example, try to read the contents of a file (as a result of which file data will usually be returned), but the file does not exist.

Delegate properties that do not always have to be set and usually set after initialization.

Like weak links in classes . What they point to can be set to nil at any time.

If you need a way to find out when the value is set (data not yet loaded> data) instead of using a separate boolean variable dataLoaded.

What is optional chaining in Swift?


The processes of requesting, invoking properties, subscripts and methods for an optional, which may have the value “nil”, are defined as an optional sequence (optional chain) .

The optional sequence returns two values ​​-
  • if the option contains a “value”, then when the properties, methods and subscripts associated with it are called, the value is returned
  • if an optional contains “nil”, all properties, methods and subscripts associated with it return nil

An optional sequence is an alternative to forced unpacking.

What is forced unwrapping?


Forced unpacking is a way to retrieve the value contained in an optional. This operation is dangerous because you are essentially telling the compiler: I am sure that this option contains a real value, extract it!

let value: Int? = 1
let newValue: Int = value! // Теперь newValue содержит 1 
let anotherOptionalInt: Int? = nil
let anotherInt = anotherOptionalInt! // Output:fatal error: внезапный nil при распаковке опционального значения.

What is implicit unwrapping?


Implicit unpacking : when we define an implicitly unpacked option, we define a container that will automatically force unpack every time we read it.

var name: String! = “Virat”
let student = name // В данный момент мы считываем текст
name = nil
let player = name //Output:fatal error: внезапный nil при распаковке опционального значения.

If the implicitly unpacked option is nil and you are trying to access its packed value, you will throw a runtime error. The result is exactly the same as if you placed an exclamation mark after the usual optional, which does not contain a value.

What is optional binding?


You can unpack options in a "safe" or "insecure" way. A safe way is to use optional binders.

Optional binding is used to determine if an optional contains a value, and if so, we will make that value available as a time constant or variable. Thus, there is no need to use a suffix! to access its value.

let possibleString: String? = "Hello"
if let actualString = possibleString {
//actualString - обычное (не опциональное) строковое значение
//равное значению, хранимому в possibleString
   print(actualString)
}
else {
  //possibleString не содержат значения, обработайте эту
  //ситуацию
}

What is Guardand what are its benefits?


The operator guardis simple and powerful. It checks some condition and, if it is evaluated as false, the else statement is executed, which usually terminates the method.

func addStudent(student: [String: String]) {
guard let name = student["name"] else {
return
}
print("Added \(name)!")
guard let rollNo = student ["rollNo"] else {
print("roll No not assigned")
return
}
print("Assigned roll no is \(rollNo).")
}
addStudent(student: ["name": "Ravi"])
// Выведет "Added Ravi!"
// Выведет "roll No not assigned"
addStudent(student: ["name": "Ravi", "rollNo": "1"])
// Выведет "Added Ravi!"
// Выведет "Assigned roll no is 1"

The advantage guardis faster execution . Guardblock is executed only if the condition is false and the output of the unit will be carried out through the control transmission operator, such as return, break, continueor thrown. This provides an early exit and fewer brackets. Early exit means faster execution.

Please refer to this article for more information.

When to use guard let, and when if let?

  • Use guardwhen you want to eliminate unexpected / incorrect input and focus on the goal if you have alternative ways of handling input.
  • Use a guardifelseblock to reduce nesting and indentation, as it is relatively compact.

What is defer?


An operator is deferused to execute a set of statements just before the execution of the code leaves the current block.

The statement deferinside the block ifwill be executed first. Then follows the LIFO template to execute the remaining deferstatements.

func doSomething() {
defer { print(“1”)}
defer { print(“2”)}
defer { print(“3”)}
if 1<2 {
defer { print("1<2")}
}
defer { print(“4”)}
defer { print(“5”)}
defer { print(“6”)}
}
Вывод 1<2 6 5 4 3 2 1

List which control transfer operators are used in Swift?


break- the operator breakimmediately completes the execution of the entire control flow statement.

continue- the operator continuetells the loop to stop what it is doing and start again at the beginning of the next iteration of the loop.
return- returns values ​​from functions.
throw- you need to forward errors using Throwing Functions
fallthrough- the operator is fallthroughused in the switch case block to execute the case statement, which is next to the corresponding case statements based on user requirements.

The swiftstatement is fallthroughused to execute the next case, even if it does not match the original.

let integerToDescribe = 5
var description = “The number \(integerToDescribe) is”
switch integerToDescribe {
case 2, 3, 5, 7, 11, 13, 17, 19:
description += “ a prime number, and also”
fallthrough
case 10:
description += “ case 10.”
default:
description += “ an integer.”
}
print(description)// Вывод:The number 5 is a prime number, and also case 10.

The end of the second part. The first part can be read here .

We are waiting for your comments and recall that in a few hours there will be an open day , in the framework of which we will talk in detail about our course.

Also popular now: