Tcl – Data Types

Tcl – Data Types ”; Previous Next The primitive data-type of Tcl is string and often we can find quotes on Tcl as string only language. These primitive data-types in turn create composite data-types for list and associative array. In Tcl, data-types can represent not only the simple Tcl objects, but also can represent complex objects such as handles, graphic objects (mostly widgets), and I/O channels. Let”s look into the details about each of the above. Simple Tcl Objects In Tcl, whether it is an integer number, boolean, floating point number, or a string. When you want to use a variable, you can directly assign a value to it, there is no step of declaration in Tcl. There can be internal representations for these different types of objects. It can transform one data-type to another when required. The syntax for assigning value to variable is as follows − Live Demo #!/usr/bin/tclsh set myVariable 18 puts $myVariable When the above code is executed, it produces the following result − 18 The above statement will create a variable name myVariable and stores it as a string even though, we have not used double quotations. Now, if we try to make an arithmetic on the variable, it is automatically turned to an integer. A simple example is shown below − Live Demo #!/usr/bin/tclsh set myVariable 18 puts [expr $myVariable + 6 + 9] When the above code is executed, it produces the following result − 33 One important thing to note is that, these variables don”t have any default values and must be assigned value before they are used. If we try to print using puts, the number is transformed into proper string. Having two representations, internal and external, help Tcl to create complex data structures easily compared to other languages. Also, Tcl is more efficient due to its dynamic object nature. String Representations Unlike other languages, in Tcl, you need not include double quotes when it”s only a single word. An example can be − Live Demo #!/usr/bin/tclsh set myVariable hello puts $myVariable When the above code is executed, it produces the following result − hello When we want to represent multiple strings, we can use either double quotes or curly braces. It is shown below − Live Demo #!/usr/bin/tclsh set myVariable “hello world” puts $myVariable set myVariable {hello world} puts $myVariable When the above code is executed, it produces the following result − hello world hello world List List is nothing but a group of elements. A group of words either using double quotes or curly braces can be used to represent a simple list. A simple list is shown below − Live Demo #!/usr/bin/tclsh set myVariable {red green blue} puts [lindex $myVariable 2] set myVariable “red green blue” puts [lindex $myVariable 1] When the above code is executed, it produces the following result − blue green Associative Array Associative arrays have an index (key) that is not necessarily an integer. It is generally a string that acts like key value pairs. A simple example is shown below − Live Demo #!/usr/bin/tclsh set marks(english) 80 puts $marks(english) set marks(mathematics) 90 puts $marks(mathematics) When the above code is executed, it produces the following result − 80 90 Handles Tcl handles are commonly used to represent files and graphics objects. These can include handles to network requests and also other channels like serial port communication, sockets, or I/O devices. The following is an example where a file handle is created. set myfile [open “filename” r] You will see more detail on files in the Tcl file I/O chapter. Print Page Previous Next Advertisements ”;

Swift – Generics

Swift – Generics ”; Previous Next Swift provides a special feature known as ‘Generic” to write flexible and reusable functions and types that can work well with any other type. Generics are used to avoid duplication and to provide abstraction. Swift has some standard libraries that are built with generics code. Arrays and dictionary types belong to a generic collection. So, we are allowed to create an array that holds a String value or can able to create an array that holds an int value. Similarly, for the dictionary. Example func exchange(inout a: Int, inout b: Int) { let temp = a a = b b = temp } var numb1 = 100 var numb2 = 200 print(“Before Swapping values are: (numb1) and (numb2)”) exchange(&numb1, &numb2) print(“After Swapping values are: (numb1) and (numb2)”) Output It will produce the following output − Before Swapping values are: 100 and 200 After Swapping values are: 200 and 100 Generic Functions Generic functions are special functions that can be used to access any data type like ”Int” or ‘String’ while maintaining the type safety. Or we can say that generic functions can work with different types without specifying the actual type at the time of declaration. Example In the following example, The function exchange() is used to swap values described in the above program and <T> is used as a type parameter. For the first time, function exchange() is called to return ”Int” values and the second call to the function exchange() will return ”String” values. Multiple parameter types can be included inside the angle brackets separated by commas. func exchange<T>(_ a: inout T, _ b: inout T) { let temp = a a = b b = temp } var numb1 = 100 var numb2 = 200 print(“Before Swapping Int values are: (numb1) and (numb2)”) exchange(&numb1, &numb2) print(“After Swapping Int values are: (numb1) and (numb2)”) var str1 = “Generics” var str2 = “Functions” print(“Before Swapping String values are: (str1) and (str2)”) exchange(&str1, &str2) print(“After Swapping String values are: (str1) and (str2)”) Output It will produce the following output − Before Swapping Int values are: 100 and 200 After Swapping Int values are: 200 and 100 Before Swapping String values are: Generics and Functions After Swapping String values are: Functions and Generics Type Parameters Type parameters are named as user-defined to know the purpose of the type parameter that it holds. Swift provides <T> as a generic type parameter name. However type parameters like Arrays and Dictionaries can also be named as key, values to identify that they belong to the type ‘Dictionary”. We are allowed to provide more than one type parameter by writing multiple type parameter names in the angle brackets, where each name is separated by a comma. Example // Generic Types struct TOS<T> { var items = [T]() mutating func push(item: T) { items.append(item) } mutating func pop() -> T? { return items.popLast() } } var tos = TOS<String>() tos.push(item: “Swift 4”) print(tos.items) tos.push(item: “Generics”) print(tos.items) tos.push(item: “Type Parameters”) print(tos.items) tos.push(item: “Naming Type Parameters”) print(tos.items) if let deletetos = tos.pop() { print(“Popped item: (deletetos)”) } else { print(“The stack is empty.”) } Output It will produce the following output − [“Swift 4”] [“Swift 4”, “Generics”] [“Swift 4”, “Generics”, “Type Parameters”] [“Swift 4”, “Generics”, “Type Parameters”, “Naming Type Parameters”] Popped item: Naming Type Parameters Generic Type and Extending a Generic Type In Swift, we are allowed to define generic types to create flexible and reusable structures, classes or enumerations that can easily work with any data type. Also, we are allowed to extend the functionality of generic types using the extension keyword. Example struct TOS<T> { var items = [T]() mutating func push(item: T) { items.append(item) } mutating func pop() -> T { return items.removeLast() } } var tos = TOS<String>() tos.push(item: “Swift 4”) print(tos.items) tos.push(item: “Generics”) print(tos.items) tos.push(item: “Type Parameters”) print(tos.items) tos.push(item: “Naming Type Parameters”) print(tos.items) extension TOS { var first: T? { return items.isEmpty ? nil : items[items.count – 1] } } if let first = tos.first { print(“The top item on the stack is (first).”) } Output It will produce the following output − [“Swift 4”] [“Swift 4”, “Generics”] [“Swift 4”, “Generics”, “Type Parameters”] [“Swift 4”, “Generics”, “Type Parameters”, “Naming Type Parameters”] The top item on the stack is Naming Type Parameters. Type Constraints Swift allows ”type constraints” to specify whether the type parameter inherits from a specific class, or to ensure protocol conformance standard. We are allowed to use them with classes and protocols to specify more complex requirements. While creating custom generic types we are allowed to create our own type constraints. Syntax Following is the syntax for the type constraints − Func functionName<T: className, U: protocolName>(variable1: T, variable2: U){ // Function body } Example // A generic function with a type constraint func show<T: CustomStringConvertible>(item: T) { print(item.description) } let str = “Welcome Swift” let number = 22 show(item: str) show(item: number) Output It will produce the following output − Welcome Swift 22 Where Clauses Type constraints enable the user to define requirements on the type parameters associated with a generic function or type. For defining requirements for associated types ”where” clauses are declared as part of the type parameter list. ”where” keyword is placed immediately after the list of type parameters followed by constraints of associated types, and equality relationships between types and associated types. Example protocol Container { typealias ItemType mutating func append(item: ItemType) var count: Int { get } subscript(i: Int) -> ItemType { get } }

Swift – Protocols

Swift – Protocols ”; Previous Next Protocols provide a blueprint for Methods, properties and other requirements functionality. It is just described as a methods or properties skeleton instead of an implementation. Methods and properties implementation can further be done by defining classes, functions and enumerations. Conformance of a protocol is defined as the methods or properties satisfying the requirements of the protocol. Defining Protocols in Swift In Swift, the definition of the protocol is quite similar to the class, structure or enumeration. A protocol is defined using the protocol keyword. Syntax Following is the syntax for the protocol − protocol SomeProtocol { // protocol definition } Protocols are declared after the class, structure or enumeration type names. Single and multiple protocol declarations are also possible. If multiple protocols are defined they have to be separated by commas. struct SomeStructure: Protocol1, Protocol2 { // structure definition } When a protocol has to be defined for a superclass, the protocol name should follow the superclass name with a comma. class SomeClass: SomeSuperclass, Protocol1, Protocol2 { // class definition } Property, Method and Initialization Requirements A protocol requires any conforming type which can provide property, method and initialization. Property Requirements − A protocol is used to specify a particular class type property or instance property. It only specifies the type or instance property rather than specifying whether it is a stored or computed property. Also, specify whether the property is ”gettable” or ”settable”. Property requirements are declared by ”var” keyword as property variables. {get set} is used to declare gettable and settable properties after their type declaration. Gettable is mentioned by {get} property after their type declaration. Syntax The following syntax is for defining properties in protocol − protocol SomeProtocol { var propertyName : Int {get set} } Method Requirements − A protocol is used to specify particular type methods or instance methods. It only contains the definition part without curly braces and body. It allows methods to have variadic parameters. Syntax The following syntax is for defining methods in protocol − protocol SomeProtocol { func methodName(parameters) } Mutating Method Requirements − If you want to specify a mutating method in the protocol then use the mutating keyword before the definition of the method. It allows structure and enumeration to adopt the protocol with the mutating method. Syntax The following syntax is for defining mutating methods in protocol − protocol SomeProtocol { mutating func methodName(parameters) } Initializer Requirements: A protocol is also used to specify an initializer that will implemented by conforming types. It only contains the definition part just like the normal initializers, but without and curly braces and a body. We can specify either designated or convenience initializers. Also, the class or structure that conforms to the protocol must use the required modifier before the implementation of the initializer. Protocol conformance is ensured on all subclasses for explicit or inherited implementation by ”required” modifier. When a subclass overrides its superclass initialization requirement it is specified by the ”override” modifier keyword. Syntax The following syntax is for defining initializers in protocol − protocol SomeProtocol { init(parameters) } Example Swift program to create a protocol that conforms by a class. // Protocol protocol classa { // Properties var marks: Int { get set } var result: Bool { get } // Method func attendance() -> String func markssecured() -> String } // Protocol protocol classb: classa { // Properties var present: Bool { get set } var subject: String { get set } var stname: String { get set } } // Class that conform Protocol class classc: classb { var marks = 96 let result = true var present = false var subject = “Swift 4 Protocols” var stname = “Protocols” func attendance() -> String { return “The (stname) has secured 99% attendance” } func markssecured() -> String { return “(stname) has scored (marks)” } } // Instance of class let studdet = classc() studdet.stname = “Swift 4″ studdet.marks = 98 // Accessing methods and properties print(studdet.markssecured()) print(studdet.marks) print(studdet.result) print(studdet.present) print(studdet.subject) print(studdet.stname) Output It will produce the following output − Swift 4 has scored 98 98 true false Swift 4 Protocols Swift 4 Example Swift program to create a protocol with mutating method requirements. // Protocol protocol daysofaweek { // Mutating method mutating func display() } // Enumeration that conforms to the Protocol enum days: daysofaweek { case sun, mon, tue, wed, thurs, fri, sat mutating func display() { switch self { case .sun: print(“Sunday”) case .mon: print(“Monday”) case .tue: print(“Tuesday”) case .wed: print(“Wednesday”) case .thurs: print(“Thursday”) case .fri: print(“Friday”) case .sat: print(“Saturday”) } } } // Instance of enumeration var res = days.wed res.display() Output It will produce the following output − Wednesday Example Swift program to create a protocol with an initializer that conforms to the class. // Protocol protocol tcpprotocol { // Initializer init(no1: Int) } class mainClass { var no1: Int // local storage init(no1: Int) { self.no1 = no1 // initialization } } // Class that conform protocol class subClass: mainClass, tcpprotocol { var no2: Int init(no1: Int, no2 : Int) { self.no2 = no2 super.init(no1:no1) } // Requires only one parameter for convenient method required override convenience init(no1: Int) { self.init(no1:no1, no2:0) } } // Class instances let obj1 = mainClass(no1: 20) let obj2 = subClass(no1: 30, no2: 50) print(“res is: (obj1.no1)”) print(“res is: (obj2.no1)”) print(“res is: (obj2.no2)”) Output It will produce the following output − res is: 20 res is: 30 res is: 50

Swift – Extensions

Swift – Extensions ”; Previous Next What are Extensions in Swift? Swift provides a special feature known as extension. Extensions are used to add new functionalities in the existing class, structure, enumeration or protocol type without overriding or modifying the existing code. This feature is useful when we want to extend the functionality of types that we cannot modify, such as third-party libraries, etc. Extensions are static additions to the type they are not dynamic. Also, they cannot add stored properties with default values. The following are the functionalities provided by the extensions − Adding computed properties and computed type properties Defining instance and type methods Providing new initializers Defining subscripts Defining and using new nested types Making an existing type conform to a protocol Defining Extensions in Swift Extensions are declared with the help of the extension keyword. Syntax Following is the syntax for the extension − extension SomeType { // Adding new functionality } Existing type can also be added with extensions to make it a protocol standard and its syntax is similar to that of classes or structures. extension SomeType: SomeProtocol, AnotherProtocol { // Describe protocol requirements } Extensions with Computed Properties Computed ”instance” and ”type” properties can also be extended with the help of extensions. Computed properties are those properties that do not store a value instead, they provide a getter and setter to retrieve and set other properties and values. Example Swift program to demonstrate how to add new functionality in the computed properties using the extension. // Adding new functionality to the computed property using an extension extension Int { var add: Int {return self + 100 } var sub: Int { return self – 10 } var mul: Int { return self * 10 } var div: Int { return self / 5 } } let addition = 3.add print(“Addition is (addition)”) let subtraction = 120.sub print(“Subtraction is (subtraction)”) let multiplication = 39.mul print(“Multiplication is (multiplication)”) let division = 55.div print(“Division is (division)”) let mix = 30.add + 34.sub print(“Mixed Type is (mix)”) Output It will produce the following output − Addition is 103 Subtraction is 110 Multiplication is 390 Division is 11 Mixed Type is 154 Extension with Initializers Swift provides the flexibility to add new initializers to an existing type using extensions. The user can add their own custom types to extend the types already defined and additional initialization options are also possible. Extensions support only init(). deinit() is not supported by the extensions. Example Swift program to demonstrate how to add new functionality in the initializer using the extension. struct sum { var num1 = 100, num2 = 200 } struct diff { var no1 = 200, no2 = 100 } struct mult { var a = sum() var b = diff() } let calc = mult() print (“Inside mult block (calc.a.num1, calc.a.num2)”) print(“Inside mult block (calc.b.no1, calc.b.no2)”) let memcalc = mult(a: sum(num1: 300, num2: 500),b: diff(no1: 300, no2: 100)) print(“Inside mult block (memcalc.a.num1, memcalc.a.num2)”) print(“Inside mult block (memcalc.b.no1, memcalc.b.no2)”) extension mult { init(x: sum, y: diff) { let X = x.num1 + x.num2 let Y = y.no1 + y.no2 } } let a = sum(num1: 100, num2: 200) print(“Inside Sum Block:( a.num1, a.num2)”) let b = diff(no1: 200, no2: 100) print(“Inside Diff Block: (b.no1, b.no2)”) Output It will produce the following output − Inside mult block (100, 200) Inside mult block (200, 100) Inside mult block (300, 500) Inside mult block (300, 100) Inside Sum Block:(100, 200) Inside Diff Block: (200, 100) Extension with Methods New instance methods and type methods can be added further to the subclass with the help of extensions. Example Swift program to demonstrate how to add new functionality in the methods using the extension. extension Int { func topics(summation: () -> ()) { for _ in 0..<self { summation() } } } 4.topics({ print(“Inside Extensions Block”) }) 3.topics({ print(“Inside Type Casting Block”) }) Output It will produce the following output − Inside Extensions Block Inside Extensions Block Inside Extensions Block Inside Extensions Block Inside Type Casting Block Inside Type Casting Block Inside Type Casting Block Extension with Mutating Instance Methods We can also add new functionality in the mutating instance methods of structure and enumeration using the extension. Example Swift program to demonstrate how to add new functionality in the mutating methods using the extension. extension Double { mutating func square() { let pi = 3.1415 self = pi * self * self } } var Trial1 = 3.3 Trial1.square() print(“Area of circle is: (Trial1)”) var Trial2 = 5.8 Trial2.square() print(“Area of circle is: (Trial2)”) var Trial3 = 120.3 Trial3.square() print(“Area of circle is: (Trial3)”) Output It will produce the following output − Area of circle is: 34.210935 Area of circle is: 105.68006 Area of circle is: 45464.070735 Extension with Subscripts Adding new subscripts to already declared instances can also be possible with extensions. Example Swift program to demonstrate how to add new functionality in the subscript using the extension. extension Int { subscript(var multtable: Int) -> Int { var no1 = 1 while multtable > 0 { no1 *= 10 –multtable } return (self / no1) % 10 } } print(12[0]) print(7869[1]) print(786543[2]) Output It will produce the following output − 2 6 5 Extension with Nested Types Nested types for class, structure and enumeration instances can also be extended with the help of extensions. Example

Swift – Methods

Swift – Methods ”; Previous Next Methods are the functions of a particular type, such as class, structure or enumeration. They define the behavior and functionality for instances of a type. They are generally accessed by the instances. Swift also supports type methods that are associated with the type itself. Instance Methods in Swift In Swift, instance methods are the functions that belong to the specific instance of a class, structure or enumeration. They are called on an instance of the type and can access and modify instance properties or other instance methods, or also add functionality related to the instance”s need. The syntax of the instance method is the same as the function. Instance method can also have, parameters, return type, parameter names, and argument labels. It can be written inside the {} curly braces. It has implicit access to methods and properties of the type instance. An instance method is called only using the instance of that particular type, we are not allowed to call an instance method without any instance. Syntax Following is the syntax of the instance method- func methodname(Parameters) -> returntype { Statement1 Statement2 — Statement N return parameters } Instance methods are accessed with ”.” dot syntax. instanceName.methodName() Example // Defining a class class Calculations { // Properties let a: Int let b: Int let res: Int // Initializer init(a: Int, b: Int) { self.a = a self.b = b res = a + b } // Instance method func tot(c: Int) -> Int { return res – c } // Instance method func result() { print(“Result is: (tot(c: 20))”) print(“Result is: (tot(c: 50))”) } } // Creating and initializing the instance of the class let pri = Calculations(a: 600, b: 300) // Accessing the instance method pri.result() Output It will produce the following output − Result is: 880 Result is: 850 Mutating Instance Method In Swift, structures and enumerations are value types, which means we cannot alter the properties inside the instance method. So to modify the properties inside a method we need to specify that method as a mutating method using the mutating keyword and the changes made by the method in its properties will written back to the original structure when the method ends. We can only mutate methods of structure and enumeration but not class because a class is a reference type so their properties can be modified without using mutating keyword. Also, we cannot call a mutating method on a constant of structure type. Syntax Following is the syntax of the mutating instance method − mutating func methodname(Parameters) -> returntype { Statement } Example Swift program to demonstrate the mutating method in structure. // Defining a structure struct CalculateSum { // Properties var num1 = 1 var num2 = 1 // Instance method func sum() -> Int { return num1 + num2 } // Mutating instance method mutating func increment(res: Int) { num1 *= res num2 *= res print(“New Number 1 is “, num1) print(“New Number 2 is “, num2) } } // Creating and initializing the instance of structure var obj = CalculateSum(num1: 10, num2: 12) // Calling mutating method obj.increment(res: 10) // Calling instance method print(“Sum is “, obj.sum()) Output It will produce the following output − New Number 1 is 100 New Number 2 is 120 Sum is 220 Assigning Instance to self within a Mutating Method In mutating methods, we are allowed to assign a new instance to the implicit self property. It will replace the existing instance with the new instance. While assigning a new instance to the self always be careful because it changes the state of the instance and any reference related to the original instance will not reflect the changes. Example Swift program to demonstrate how to assign an instance to self within a mutating method. // Defining a structure struct Student { var age: Int var name: String // Mutating method that assigns a new instance to self mutating func newValue() { self = Student(age: 23, name: “Jyoti”) } } // Creating an instance of the Student structure var obj = Student(age: 22, name: “Poonam”) // Calling the mutating method obj.newValue() // Displaying the updated values print(“New age: (obj.age), New name: (obj.name)”) Output It will produce the following output − New age: 23, New name: Jyoti Method Argument label and Parameter name in Swift Just like a function, a method can also have labels and names for its arguments and parameters. These labels and names provide a clear and descriptive context for the argument and parameter. The parameter name is used in the declaration of the method whereas the argument label is used when the method is called. By default, the argument label and parameter name are the same, but multiple parameters can have the same or unique argument label. The names of the parameters should be unique so that the compiler can easily distinguish them. We can also ignore the argument label by placing the underscore(_) before the name of the parameter. Syntax Following is the syntax for the argument label and parameter name − // Parameter name With argument label func methodname(argumentLabel parameterName: Type, parameterName: Type) -> returntype { Statement return value } methodname(name1:value, name2: value) // Parameter name without argument label func methodname(_name1: Type, _name2: Type) -> returntype { Statement return value } methodname(value1, value2) Example Swift program to demonstrate how to specify the parameter name and argument label in the method. // Defining class class CalculateSum { // Method with parameter name and argument label func addingTwoNumbers(num1 x:

Swift – Function vs Method

Swift – Function vs Method ”; Previous Next In Swift, functions and methods both are fundamental building blocks for optimizing and encapsulating code. It might be confusing to understand the difference between function and method, but we might think they are both the same. That”s not true. The methods are used in class, struct, and enum. They are called on the instances of that type and access and modify the properties of the instance. Whereas functions are defined independently or globally without creating a class or structure. Or we can say that a method is a function while a function is not a method. Swift Functions Functions are used to perform specific actions and are called by their names. It is very simple to pass the variables or constants as an argument while calling a function. Also, we can return a value from a function of any type. A function that works independently of a file can also be defined outside of it. Syntax Following is the syntax of a function − func functionName(parameters…) -> returnType { //Write statements here to perform actions } Example Swift program to demonstrate how to create and call a function. // Function without return value func show(msg: String) { print(“Welcome to, (msg)!”) } // Function call show(msg: “Tutorials Point”) // Function with return value func sumOfNumbers(_ nums: [Int]) -> Int { var sum = 0 // Calculating the sum of the numbers present in the array for n in nums { sum += n } return sum } // Function call with return value let inputNumbers = sumOfNumbers([3, 5, 6, 7, 1]) print(“Sum = (inputNumbers)”) Output It will produce the following output − Welcome to, Tutorials Point! Sum = 22 Swift Methods A method is a function and can be defined in classes, structures, and enumerations. Using methods, we can perform certain actions according to your requirements. As per our needs, we can define more than one method to perform different tasks. To access the defined methods in a class or structure we have to create an instance of the associated type. Using that object, we can call methods to perform tasks. Just like functions, we can also pass arguments while calling the method. Always remember that without creating an object of that class or struct we cannot access the methods. In the Swift language, there are two types of methods like the following − Instance Methods − As per their names, these are the instance-specific methods that can be called through the instances. The compiler will give us an error if we will try to access the methods without an instance of that class or struct. Also, we cannot call the methods of a class (for eg. Class Student) from another class”s instance. Type Methods − In Swift, we can define the type methods with prefix keywords like static or class. There is no need to create an instance of a class or struct to call type methods. They can be called directly from the type name. Syntax Following is the syntax of a method − func methodName(parameters…) -> returnType { //Write statements here to perform actions } Example Swift program to demonstrate how to create and call a method. // Defining a structure struct Student { // Properties let name: String let grade: Int // Instance method func displayInfo() { print(“name: (name)”) print(“grade: (grade)”) } // Type method static func dummyStudents() -> [Student] { return [Student(name: “Ray Sin”, grade: 4), Student(name: “Cherry Blossom”, grade: 2), Student(name: “Perry Scope”, grade: 7)] } } // Creating instance of the structure let anne = Student(name: “Anne Teak”, grade: 5) // Calling instance method from object anne anne.displayInfo() // Calling type method let students = Student.dummyStudents() print(“number of students: “, students.count) Output It will produce the following output − name: Anne Teak grade: 5 number of students: 3 Visual Identification Between Function and Method The Swift language shows how a function and method are denoted. It is visible that both are denoted as follows − The function has an icon like ƒ. The method has an icon of M. Difference Between Methods and Functions in Swift The following table will show the major difference between the methods and functions in Swift − Function Method The function is defined as independent. So that, we can define functions outside of the class. They are connected with a class or struct itself. Outside the scope, you can not define the methods. Functions are independent properties of structured languages like C/C++. Methods works within the scope of an object similar to Object-oriented languages like C#, Java, Swift, etc. Functions don”t capture any reference variables or constants. Methods are called using reference variables (or instances) only. While functions do not belong to classes, they perform individually. Methods are defined to manipulate the particular instance of that class or struct. No need to create objects to call them. An object is required to access them. Simply, every function is not a method. While every method is a function. Print Page Previous Next Advertisements ”;

Swift – Concurrency

Swift – Concurrency ”; Previous Next Concurrency provides the ability for Swift program to execute multiple tasks or operations simultaneously. Or we can say that it allows us to write asynchronous and parallel codes in a structured way. We are allowed to suspend and resume asynchronous code. Concurrency will improve the responsiveness and performance of the application. Asynchronous Functions In Swift, asynchronous functions or methods are the special type of functions or methods that can perform non-blocking and asynchronous operations. Such types of functions can be suspended in between their execution or they can also pause to wait for something. Also, we are allowed to mark the places where we want to suspend the execution of the function. To create a synchronous function or method we have to use the async keyword in the declaration part after the parameter list and before the return arrow. Syntax Following is the syntax for asynchronous function − func functionName(parameter) async -> returnType{ // statement } To suspend the execution of the asynchronous function or method until the awaited asynchronous operation completes, we have to use the await keyword in front of the call. It makes concurrent code easier to read. Following is the syntax for suspending the execution of asynchronous functions − await functionName(parameter) Asynchronous function or method can also throw an error and we can handle that error with the help of try and catch block. Following is the syntax for handling errors by asynchronous functions − func functionName() async throws -> Data { // asynchronous code that may throw an error } do { let data = try await functionName() // process data } catch { // handle error } We can also call asynchronous functions in parallel by using the async keyword in front of let while defining a constant and then writing the await keyword whenever we use the constant. Following is the syntax for calling asynchronous functions in parallel − // Calling asynchronous function in parallel async let result1 = functionName1(parameter) async let result2 = functionName2(parameter) // Suspend execution let suspendExecution = await[result1, result2] Example Swift program for asynchronous function. // Asynchronous function func randomFunc() async -> Int { Int.random(in: 10…40) } let result = await randomFunc() print(“Random Number:”, result) Output It will produce the following output − Random Number: 13 Task and Task Group In Swift, task and task groups are the main concepts that help us to work with asynchronous code in a structured manner. A task is a unit of work that can be executed concurrently. All the asynchronous codes that execute are part of the task. Generally, a task can perform one operation at a time but when we create multiple tasks then Swift will schedule them to run simultaneously. Whereas a task group is used to manage a collection of tasks and collectively perform operations on them. Here the tasks are arranged in a hierarchy, which means each task in the given group has the parent task and child tasks and this relationship is important because − While working with a parent task, you cannot forget to wait for its task to complete. If you set the priority of the child task to high then the priority of the parent task will automatically be set to high. If the parent task gets cancelled, then the child task will also cancelled. The local values of tasks can easily propagate to child tasks Task Cancellation We are allowed to cancel the execution of the task. Or we can terminate the ongoing task before it is completed. It is helpful in various cases like cleaning up resources and stopping long running operations. We can cancel the task with the help of the cancel() method provided by Swift. Example Swift program to create and cancel a task. import Foundation class MyTaskManager { private var task: DispatchWorkItem? func createTask() { // Create a DispatchWorkItem task = DispatchWorkItem { for i in 1…5 { if self.task?.isCancelled ?? false { print(“Task cancelled”) return } print(“Running task – (i)”) } print(“Task completed successfully”) } // Execute the task on a background queue DispatchQueue.global().async(execute: task!) } func cancelTask() { // Cancelling the task task?.cancel() } } let obj = MyTaskManager() // Create and run the task obj.createTask() // Wait for a while sleep(2) // Cancel the task obj.cancelTask() Output It will produce the following output − Running task – 1 Running task – 2 Running task – 3 Running task – 4 Running task – 5 Task completed successfully Actor As we know tasks are used to break our programs into isolated or concurrent pieces, which makes them run safely at the same time. And to add some information between these tasks Swift provides Actors. Actors are reference types and it allows only one task to access its mutable state at a time. That makes code run safely in multiple tasks and can easily interact with the same instance of an actor. In actor, if outside code tries to access the properties directly, then we will get an error. We can declare an actor with the help of the actor keyword. Also, we are allowed to create instances of actor just like class and structure to access the properties and methods of the actor. To suspend the execution of the actor we can use the await keyword. Syntax Following is the syntax for calling asynchronous functions in parallel − // Calling asynchronous function in parallel async let result1 = functionName1(parameter) async let result2 = functionName2(parameter) // Suspend execution let suspendExecution = await[result1, result2] Example

Swift – Nested Types

Swift – Nested Types ”; Previous Next The nested type is a very powerful tool in Swift programming. Using nested type we can able to easily nest enumerations, classes and structures into other enumerations, classes and structures. Using nested type we can nest an enumeration or class into a structure or vice versa. So we can say that by using nested types we can create complex custom types. Nested types are commonly used to create well-organized and hierarchical programs. They are also used to encapsulate code so that we can easily understand it. They also reduce namespace conflicts. Creating Nested Types We can create nested types by defining a structure into another structure or a class into another class just like the nested functions. We can create multiple structures, classes and enumerations in another structure, class and enumerations. Syntax Following is the syntax of the nested types − Struct Name{ Struct name{ // body } } Using this syntax we can nest classes and enumerations. Example Suppose we are creating a structure of a car in which we have multiple types of features like colour and sunroof. So using nested type we can define each type of specifications. struct Car{ struct Color{ var single: String var double: String var customize: String } struct Sunroof{ var half: String var full: String } } Creating Instance of Nested Types We can create instances of nested types using the dot operator. So simply prefix the name of the outer type followed by the dot operator and then specify the nested type name. Every nested type has its instance. Syntax Following is the syntax for creating instances of nested types − let name = outerTypeName.nestedTypeName(value: type) Or, var name = OuterTypeName(label1:Value, lable2: OuterTypeName.NestedTypeName(label: Value, lable2: Value)) Example Let”s create the instance of the above-nested types − let instance1 = Car.Color(single: “Yellow”, double: “Green Black”, customize: “Blue”) let instance2 = Car.Sunroof(half: “yes”, full: “No”) Or, var myCar = Car(name:”Breeza”, color: Car.Color( single: “Blue”, double: “No”, customize: “White”), sunroof:Car.Sunroof(half: “Yes”, full: “No”)) The complete example is − import Foundation // Outer sturtcure struct Car{ // Nested structure 1 struct Color{ var single: String var double: String var customize: String } // Nested structure 1 struct Sunroof{ var half: String var full: String } // Properties var name: String var color: Color var sunroof:Sunroof } // Creating instance of Car structure var myCar = Car(name:”Breeza”, color: Car.Color(single: “Blue”, double: “No”, customize: “White”), sunroof:Car.Sunroof(half: “Yes”, full: “No”)) // Displaying Data print(“Car name:”, myCar.name) print(“Car Color:”, myCar.color.single) print(“Have half Sunroof:”, myCar.sunroof.half) Output It will produce the following output − Car name: Breeza Car Color: Blue Have half Sunroof: Yes Enumerations within Structure Using nested types it is not necessary that you can only nest a structure into another structure. We can also nest an enumeration inside another structure or vice versa. Example Swift program to nest enumeration inside a structure. import Foundation // Outer structure struct Tutorialspoint { // Nested enum enum Department { case HR case Development case Designing case ContentWriting } // Properties var name: String var location: String var department: Department init(name: String, location: String, department: Department) { self.name = name self.location = location self.department = department } // Method func employeeDetail() { print(“Name: (name)”) print(“Location: (location)”) print(“Department: (department)”) } } let report = Tutorialspoint(name: “Mona”, location: “Hyderabad”, department: .Designing) report.employeeDetail() Output It will produce the following output − Name: Mona Location: Hyderabad Department: Designing Structure within Class Using nested types we are allowed to nest a structure within a class or a class within a structure without getting any error. Example Swift program to nest structure inside another class. import Foundation // Outer class class XYZCollege { // Nested structure struct StudentDetail { var name: String var age: Int var subject: String var year: Int } // Properties var department: String var details: [StudentDetail] init(department: String) { self.department = department self.details = [] } // Method 1 func newStudents(student: StudentDetail) { details.append(student) } // Method 2 func studentsData() { print(“department name: (department):”) for s in details { print(“name: (s.name), age: (s.age), subject: (s.subject), year: (s.year)”) } } } // Creating instances let s = XYZCollege(department: “Science”) let stud1Detail = XYZCollege.StudentDetail(name: “Mona”, age: 19, subject: “Maths”, year: 1) let stud2Detail = XYZCollege.StudentDetail(name: “Pihu”, age: 18, subject: “Chemistry”, year: 1) let stud3Detail = XYZCollege.StudentDetail(name: “Suman”, age: 19, subject: “Maths”, year: 1) // Accessing the methods s.newStudents(student: stud1Detail) s.newStudents(student: stud2Detail) s.newStudents(student: stud3Detail) s.studentsData() Output It will produce the following output − department name: Science: name: Mona, age: 19, subject: Maths, year: 1 name: Pihu, age: 18, subject: Chemistry, year: 1 name: Suman, age: 19, subject: Maths, year: 1 Print Page Previous Next Advertisements ”;

Swift – Auto Closures

Swift – Auto Closures ”; Previous Next A closure is a self-contained block of functionality that can passed around and used inside the code to perform any specific task. It can be assigned to a variable or passed as a function parameter. It can capture values from its surrounding context which is useful while working with asynchronous tasks. Swift supports various types of closures like escaping, non-escaping, and Auto closures. In this chapter, we will discuss about auto closure in detail. Auto Closures in Swift Swift supports a special type of closure that is known as auto closure. An auto closure is automatically created to wrap a statement that will passed as an argument to a specified function. It does not take any argument and only returns the value of the expression that it wraps inside at the time of calling. It is generally used with the function that takes closure as an argument and allows us to delay the evaluation of the expression until it is called or required. Auto closure provides a concise syntax and is useful for passing a simple expression to the function as an argument instead of creating a separate closure. Also, remember that do not overuse auto closure because it makes our code harder to read. Declaring Auto Closure To declare a closure as an auto closure we have to use the @autoclosure keyword. Syntax Following is the syntax for auto closure − func functionname(_closureParameter: @autoclosure() -> ReturnType){ // body } Example Swift simple program to demonstrate auto closure. import Foundation // Defining a function that takes an auto-closure func functionForAutoclosure(myClosure: @autoclosure () -> Void) { print(“Performing Action”) myClosure() } // Calling the function with a closure as an argument functionForAutoclosure(myClosure: print(“Hello! This is the auto closure”)) Output It will produce the following output − Performing Action Hello! This is the auto closure Example Swift program to add two numbers using auto closure. // Function to find the sum of two numbers using auto-closure func addition(_ x: Int, _ y: Int, add: @autoclosure () -> Int) { let output = x + y + add() print(“The sum of (x) and (y) is (output)”) } // Calling the function with a closure as an argument addition(2, 4, add: 7 + 8) Output It will produce the following output − The sum of 2 and 4 is 21 Auto Closures as an Escape Closure In Swift, we are allowed to escape an auto closure. An escaping closure is a special closure that passes as an argument to a function but is called after the function return. Auto closure and escaping closure both are different terms but we can combine them to delay the evaluation of the expression until it is required. To declare an auto closure as an escape closure we have to use both the @autoclosure and @escaping keywords together. Syntax Following is the syntax for auto closure as an escape closure − func functionName(_closureParameter: @autoclosure @escaping() -> ReturnType){ // body } Example Swift simple program to demonstrate auto closure as an escaping closure. import Foundation class AutoClosureExample { var queue: [() -> Void] = [] // Method that takes an auto closure as an escaping closure func closureToQueue(_ myClosure: @autoclosure @escaping () -> Void) { queue.append(myClosure) } // Method that executes the closures in the queue func runClosure() { for closure in queue { closure() } } } // Creating object of AutoClosureExample class let obj = AutoClosureExample() // Using an auto closure as an escaping closure obj.closureToQueue(print(“My Closure 1”)) obj.closureToQueue(print(“My Closure 2″)) // Activating the passage of time DispatchQueue.main.asyncAfter(deadline: .now() + 2) { // Execute the closures in the queue obj.runClosure() } Output It will produce the following output − My Closure 1 My Closure 2 This program will run on Xcode or local Swift playground. It does not work on online Swift compilers because online Swift compilers are not compatible with executing asynchronous operations. Print Page Previous Next Advertisements ”;

Swift – ARC Overview

Swift – ARC Overview ”; Previous Next Automatic Reference Counting in Swift Automatic Reference Counting(ARC) is a memory management mechanism used by Swift, it automatically tracks and manages the allocation and deallocation of objects’s memory. Or we can say that it is used to initialize and deinitialize the system resources thereby releasing memory spaces used by the class instances when the instances are no longer needed. It keeps track of information about the relationships between the instances to manage the memory resources effectively. ARC is generally applicable only to instances of classes because they are reference types. Working of ARC ARC allocates a chunk of memory to store the information whenever a new class instance is created by init(). Information about the instance type and its values are stored in the memory. When the class instance is no longer needed it automatically frees the memory space by deinit() for further class instance storage and retrieval. ARC keeps in track of currently referring class instances properties, constants and variables so that deinit() is applied only to those unused instances. ARC maintains a ”strong reference” to those class instance properties, constants and variables to restrict deallocation when the class instance is currently in use. Example Swift program to demonstrate ARC. class StudDetails { // Properties var stname: String var mark: Int // Initializer to initialize instances of the class init(stname: String, mark: Int) { self.stname = stname self.mark = mark } // Deinitializer to deinitialize the instances of // the class when they are no longer required deinit { print(“Deinitialized (self.stname)”) print(“Deinitialized (self.mark)”) } } // Creating class instance var obj1 = StudDetails( stname:”Swift”, mark:98) // Creating another class instance var obj2: StudDetails? = StudDetails(stname: “iOS”, mark: 95) // Setting anotherObj to nil to deallocate the memory obj2 = nil Output It will produce the following output − Deinitialized iOS Deinitialized 95 Strong Reference Cycles Between Class Instances in Swift ARC is used to automatically manage memory by keeping track of object references. However, there is a challenge faced by the developers which is the creation of a strong reference cycle, where two or more objects have strong references to each other which prevents their reference counts from reaching zero and due to this a memory leakage happens. Example Swift program to demonstrate strong reference cycles between class instances in Swift. class studmarks { let name: String var stud: student? // Initializer init (name: String) { print(“Initializing: (name)”) self.name = name } // Deinitializer deinit { print(“Deallocating: (self.name)”) } } class student { let name: String var strname: studmarks? // Initializer init (name: String) { print(“Initializing: (name)”) self.name = name } // Deinitializer deinit { print(“Deallocating: (self.name)”) } } // Declare optional variables for instances var shiba: studmarks? var mari: student? shiba = studmarks(name: “Swift 4”) mari = student(name: “ARC”) // Create a strong reference cycle by assigning references to each other shiba!.stud = mari mari!.strname = shiba Output It will produce the following output − Initializing: Swift 4 Initializing: ARC To resolve strong reference cycles Swift provides Weak and Unowned References. These references are used to enable one instance to refer to other instances in a reference cycle. Then the instances may refer to every instance instead of caring about a strong reference cycle. Weak References It is an optional reference to an object that does not keep a strong hold on the object. It will return nil when the object it refers to is deallocated. It is generally used where the referenced object’s lifecycle is not guaranteed to outlive the referencing object. It is commonly used for relationships where the referenced object can deallocate independently. We can declare weak references using the weak Keyword. Syntax Following is the syntax for weak reference − class Class1 { var name: Name? } class Name { weak var teacher: Class1? } Example Swift program to demonstrate weak references. class module { let name: String init(name: String) { self.name = name } var sub: submodule? deinit { print(“(name) Is The Main Module”) } } class submodule { let number: Int init(number: Int) { self.number = number } weak var topic: module? deinit { print(“Sub Module with its topic number is (number)”) } } var toc: module? var list: submodule? toc = module(name: “ARC”) list = submodule(number: 4) toc!.sub = list list!.topic = toc toc = nil list = nil Output It will produce the following output − ARC Is The Main Module Sub Module with its topic number is 4 Unowned References It is a non-optional reference to an object that does not keep a strong hold on the object as compared to a weak reference. It assumed that the reference object will never become nil, while the reference object is still alive. It is generally used where you know that the referenced object’s life is guaranteed to be at least as long as the referencing object’s lifetime. It is commonly used for relationships where the referenced object has the same or longer lifetime as compared to the referencing object. We can declare unowned references using the unowned Keyword. Syntax Following is the syntax for unowned reference − class Class1 { var name: Name? } class Name { unowned var teacher: Class1 } Example Swift program to demonstrate Unowned references. class student { let name: String var section: marks? init(name: String) { self.name = name } deinit { print(“(name)”) } } class marks { let marks: Int unowned let stname: student init(marks: Int, stname: student) { self.marks = marks