Java and Swift comparison (2) Basic type / arithmetic expression / control syntax / function definition

Introduction

This page mainly deals with Java / Swift notation of "basic types", "arithmetic expressions", "control syntax", and "function definitions" that are often used. This article is based on 1.7 for Java and Swift3 for Swift, but I'm sorry if there is a notation mistake.

-Comparison between Java and Swift (1) Source control / Scope / Variables --Comparison between Java and Swift (2) Basic type / Arithmetic / Control syntax / Function definition -Comparison between Java and Swift (3) Class implementation / Class inheritance / Class design

Introduction of basic types

Java

Array

Java arrays are declared as "type name [] variable name;".

python


String[] hoge;

However, Java arrays are not variable-length arrays because they cannot be resized after they are initialized and instances are secured in the heap area. When using it, it is necessary to specify the size that can be stored in advance as "type name [] variable name = new type name [0];" and perform initialization. It is also possible to set "type name [] variable name = {value, value, value ...};" as the initial value at the same time as the declaration.

To access the elements of an array, use "Number of arrays [index]". The first index starts at 0, for example, the last index of an array declared with a size of "3" is "size -1" and "2". If you try to operate on an element that is out of size, you will get an exception.

python


String[] hoge = new String[3]; //Secure a size 3 array
hoge = new String[]{"a", "b", "c"}; //It is also possible to substitute the initial value and initialize

System,out.println(hoge[1]); // "b"And output

// hoge[3] = 1; //An exception is thrown when trying to operate outside the range

If you change the value after getting the elements in the array, the elements in the array itself will also be affected.

python


String[] hogeA= new String[]{"a", "b", "c"};
hogeA[0] = "x";
System.out.println(hogeA[0]); // "x"And output

Also, because Java arrays have reference-type properties, if you assign an array to a variable in another array and manipulate the array variable to which it is assigned, it will also be affected by the assigned array.

python


String[] hogeA;
String[] hogeB = new String[]{"a", "b", "c"};

hogeA = hogeB;

hogeB[0] = "x";

System.out.println(hogeB[0]); // "x"And output
System.out.println(hogeA[0]); // "x"And output

List Java "List" is one of the collection frameworks, and it is a type that allows duplicate elements and can add elements in order. Since "List" will be the interface described later, there are mainly ArrayList and LinkedList as instantiated data types. In the declaration of the List variable, List is the interface, so declare "List variable name = new List interface implementation class <> ();". Specify the type name of the element you want to store by using the generics "<>" described later.

python


List<String> hoge = new ArrayList();

When adding an element to List, "List variable.add (value)" will automatically increase the size and add the element. However, note that the types of elements that can be stored in a Java List are limited to object types, and primitive types (indicating int, char, long, etc.) cannot be stored as elements. You can access the elements of List with "List variable name.get (index)". You can change it with "Variable name.set (index, value)". The first index starts at 0, for example, the last index of a List of size "3" is "Size -1" and "2". If you try to operate on an element that is out of size, you will get an exception.

python


List<Integer> test = new ArrayList<>();
test.add(1);
test.add(2);
test.add(3);

test.set(2, 9);
// System.out.println(test.get(3)); //An exception is thrown when trying to operate outside the range

If you change the value after getting the elements in the List, the elements in the List itself will also be affected.

python


//* Implementation of Test class is omitted.
List<Test> test = new ArrayList<>();

Test a1 = new Test();
a1.a1 = "1";
test.add(a1);
        
Test a2 = new Test();
a2.a1 = "2";
test.add(a2);

System.out.println(test); // ["1", "2"]Is output
        
Test q = test.get(1);
q.a1 = "A";
System.out.println(test); // ["1", "A"]Is output

However, the following example produces the following results:

python


//* Implementation of Test class is omitted.
List<Test> test = new ArrayList<>();

Test a1 = new Test();
a1.a1 = "1";
test.add(a1);
        
Test a2 = new Test();
a2.a1 = "2";
test.add(a2);

System.out.println(test); // ["1", "2"]Is output
        
Test q = test.get(1);
Test a3 = new Test();
a3.a1 = "3";
q = a3;

System.out.println(test); // ["1", "2"]Is output

In this example, when the "q" obtained by "String q = test.get (1);" is changed to "q = a3;", the reference of "q" becomes a3, but the List " The reference to the element at index 1 of "test" indicates a1. In other words, the reference has changed, so in this example it has no effect on the elements of List "test".

In addition, Java List has a reference type property, so if you assign a List variable to a variable of another List and operate the List variable of the assignment destination, it will be affected by the assigned List variable.

python


List<Test> hogeA;
List<Test> hogeB = new ArrayList<>();

Test a1 = new Test();
a1.a1 = "1";
hogeB.add(a1);
Test a2 = new Test();
a2.a1 = "2";
hogeB.add(a2);
Test a3 = new Test();
a3.a1 = "3";
hogeB.add(a3);

hogeA = hogeB;

hogeB.get(0).a1 = "x";

System.out.println(hogeA.get(0)); // "x"And output
System.out.println(hogeB.get(0)); // "x"And output

Map

Java's "Map" is one of the collection frameworks and is a type that can store values in key-value format. You can treat it like a Swift dictionary. Since "Map" will be the interface described later, the instantiated data types are mainly HashMap, TreeMap, and LinkedHashMap. Dictionary is a similar type that can store values in key-value format, but Hashtable of this data type is less convenient than Map (slow, cannot store null, etc.), and currently uses "Map". Most of them. To declare a Map variable, since Map is an interface, declare "Map <element key type name, element value type name> variable name = new Map interface implementation class <> ();". Specify the type name of the element you want to store by using the generics "<>" described later. Also, HashMap, TreeMap, and LinkedHashMap belong to the java.util package, so you need to import the class from the java.util package when using it.

python


Map<String, String> hoge = new HashMap();

When adding an element to Map, "Map variable.put (key, value)" will automatically increase the size and add the element with the specified key and value. At this time, if a key value that overlaps with the existing key is specified, it will be overwritten. However, note that the key and value types of elements that can be stored in Java Map are limited to object types, and primitive types (indicating int, char, long, etc.) cannot be stored as elements. To access the elements of Map, you can access with "Map variable name.get (key)". To remove the element, use "Map variable name.remove (key)" with the specified key value.

python


Map<Integer, Integer> test = new HashMap<>(); //Since Integer is an object type, it can be specified as an element key and value type.

test.put(1, 11);
test.put(2, 12);
test.put(3, 13);
test.put(4, 14);

test.remove(3);

System.out.println(test); // {1=11, 2=12, 4=13}Is output

If you change the value after getting the elements in the Map, the elements in the Map itself will also be affected.

python


//* Implementation of Test class is omitted.
Map<Integer, Test> test = new HashMap<>();

Test a1 = new Test();
a1.a1 = "1";
test.put(1, a1);
        
Test a2 = new Test();
a2.a1 = "2";
test.put(2, a2);

System.out.println(test); // {1=1, 2=2}Is output
        
Test q = test.get(1);
q.a1 = "A";
System.out.println(test); // {1=A, 2=2}Is output

However, the following example produces the following results:

python


//* Implementation of Test class is omitted.
Map<Integer, Test> test = new HashMap<>();

Test a1 = new Test();
a1.a1 = "1";
test.put(1, a1);

Test a2 = new Test();
a2.a1 = "2";
test.put(2, a2);

System.out.println(test); // ["1", "2"]Is output

Test q = test.get(1);
Test a3 = new Test();
a3.a1 = "3";
q = a3;

System.out.println(test); // ["1", "2"]Is output

In this example, when the "q" obtained by "Test q = test.get (1);" is changed to "q = a3;", the reference of "q" becomes a3, but the Map "test" is still used. The reference to the element of the key "1" of "" indicates a1. In other words, the reference has changed, so in this example it does not affect the elements of Map "test".

Also, since it is the key reference that is used as the key, even if the same instance is reused and added to the Map variable, it will be regarded as the same key.

python


//* Implementation of Test class is omitted.
java.util.Map<Test, String> test = new java.util.HashMap<>();

Test a1 = new Test();

a1.a1 = "1";
test.put(a1, "A"); // (1)Add instance as key

a1.a1 = "2";
test.put(a1, "B"); // (2)Add in the same instance

System.out.println(test); // (2)Overwritten as the value added in{2=B}Is output

In addition, Java Map has a reference type property, so if you assign a Map variable to another Map variable and manipulate the assigned Map variable, it will be affected by the assigned Map variable.

python


Map<Integer, Test> hogeA;
Map<Integer, Test> hogeB = new HashMap();

Test a1 = new Test();
a1.a1 = "1";
hogeB.put(1, a1);
Test a2 = new Test();
a2.a1 = "2";
hogeB.put(2, a2);
Test a3 = new Test();
a3.a1 = "3";
hogeB.put(3, a3);

hogeA = hogeB;

hogeB.get(1).a1 = "x";

System.out.println(hogeA.get(1)); // "x"And output
System.out.println(hogeB.get(1)); // "x"And output

Other comparison with Swift

Below is a comparison of Java and Swift data types.

Swift

Array

The Swift array declares "var variable name: [type name] = []". You can also declare "var variable name: Array = Array ()". It is also possible to set "var variable name: type name [] = [value, value, value ...]" as the initial value at the same time as the declaration. The Swift array is a variable length array, and if you enter "array variable name.append (value)", the size will be automatically expanded and elements will be added. In the case of Swift, there is no need to specify the size in advance, and it can be used like a Java List type.

python


var test:[Int] = [] //For Swift, you don't have to specify the size in advance

test.append(1) //Automatically expanded due to variable length array

To access the elements of the array, use "Array variable name [index]". The first index starts at 0, for example, the last index of an array declared with a size of "3" is "size -1" and "2".

If you change the value after getting the elements in the array, the elements in the array itself will also be affected.

python


var test:[Int] = [1, 2, 3]
test[0] = 9
print(test); // [9, 2, 3]And output

However, the following example produces the following results:

python


//* Implementation of Test class is omitted.
var a1 = Test(a1: 1)
var a2 = Test(a1: 2)
var a3 = Test(a1: 3)
var test:[Test] = [a1, a2, a3]
print(test); // [Test(a1: 1), Test(a1: 2), Test(a1: 3)]And output

var q = test[0]
var temp:Test = Test(a1: 9)
q = temp
print(test); // [Test(a1: 1), Test(a1: 2), Test(a1: 3)]And output

In this example, when "q" obtained by "var q = test [0]" is changed to "q = temp", the reference of "q" becomes temp, but index 1 of the array "test" is still used. The element reference to indicates a1. In other words, the reference has changed, so in this example it does not affect the elements of Map "test".

However, this does not apply when rewriting directly, such as "test [0] = Test (a1: 9)".

//* Implementation of Test class is omitted.
var a1 = Test(a1: 1)
var a2 = Test(a1: 2)
var a3 = Test(a1: 3)
var test:[Test] = [a1, a2, a3]
print(test); // [Test(a1: 1), Test(a1: 2), Test(a1: 3)]And output

test[0] = Test(a1: 9)
print(test); // [Test(a1: 9), Test(a1: 2), Test(a1: 3)]And output
print(a1); // [Test(a1: 1)And output

Also, unlike Java, Swift arrays are value types rather than reference types. If you assign an array to a variable of another array and manipulate the array variable of the assignment destination, the assigned array is not affected.

python


var test1:[Int] = [1, 2, 3]
var test2:[Int] = [4, 5, 6]

test2 = test1 //Assign to another array variable(※1)

test1[0] = 9
print(test1); // [9, 2, 3]And output
print(test2); // (※1)Because the array itself is a value type[1, 2, 3]Is output

dictionary

A dictionary is a type that can store values in key-value format. Declare "var variable name: [element key type name, element value type name] = [:]". You can also declare "var variable name: Dictionary <element key type name, element value type name> = [:]". It is also possible to set "var variable name: Dictionary <element key type name, element value type name> = [element key: element value, element key: element value ...]" at the same time as the declaration.

python


var test1:[Int:String] = [:]
var test2:Dictionary = Dictionary<Int, String>() //It is also possible to declare it as shown on the left

When adding an element to the dictionary, "Dictionary variable name [element key] = element value" will add the element to the existing dictionary. At this time, if a key value that overlaps with the existing key is specified, it will be overwritten. The element is removed by specifying the "nil" value with "Dictionary variable name [key] = nil" with the specified key value. To access the elements of the dictionary, you can access it with "Dictionary variable name [key]".

If you change the value after getting the elements in the dictionary, the elements in the dictionary itself will also be affected.

python


//* Implementation of Test class is omitted.
var items: Dictionary<Int, Test> = [:]

items[1] = Test(a1: 1)
print(items[1]!.a1) //Is output as 1

var q = items[1]!
q.a1 = 9
print(items[1]!.a1) //Is output as 9

However, the following example produces the following results:

python


//* Implementation of Test class is omitted.
var items: Dictionary<Int, Test> = [:]

var a1 = Test(a1: 1)
items[1] = a1
print(items[1]!.a1) //Is output as 1

var q:Test  = items[1]!
var a3:Test = Test(a1: 9)
q = a3

print(items[1]!.a1) //Is output as 1

In this example, when the "q" obtained by "var q: Test = items [1]!" Is changed to "q = a3", the reference of "q" becomes a3. Still, the key of the dictionary "test" The reference to the element "1" indicates a1. In other words, the reference has changed, so in this example it does not affect the elements of Map "test".

However, this does not apply when rewriting directly, such as "test [1] = Test (a1: 9)".

//* Implementation of Test class is omitted.
var items: Dictionary<Int, Test> = [:]

var a1 = Test(a1: 1)
items[1] = a1
print(items[1]!.a1) //Is output as 1

items[1] = Test(a1: 9)

print(items[1]!.a1) //Is output as 9
print(a1.a1) //Is output as 1

In addition, the element value can specify any data type, but if you want to specify an object as a key, the key object must implement the Hashable protocol.

Implementation example of dictionary Hashable protocol

python


///Must comply with the Hashable protocol to use TestClass as a dictionary key
public class TestClass : Hashable {
    var a1:String = ""
    init (a1:String) {
        self.a1 = a1
    }
    ///Hash values used in Equatable implementations
    public var hashValue: Int {
        get {
            ///If this hash value is the same, it will be treated as the same in the dictionary.
            return a1.hashValue
        }
    }
}

///Equatable implementation of TestClass
func == (lhs:TestClass, rhs:TestClass) -> Bool {
    return lhs.hashValue == rhs.hashValue
}

python


var items: Dictionary<TestClass, Int> = [:]
var a1:TestClass = TestClass(a1 : "A")
var a2:TestClass = TestClass(a1 : "B")
var a3:TestClass = TestClass(a1 : "C")
var a4:TestClass = TestClass(a1 : "D")
var a5:TestClass = TestClass(a1 : "A")

items[a1] = 1
items[a2] = 2
items[a3] = 3
items[a4] = 4
items[a5] = 5
for (k, v) in items { // A : 5、B : 2、C : 3、D :Is output as 4
    print(k.a1 + " : " + v.description)    
}

In the above example, another instance is created with "var a1: TestClass = TestClass (a1:" A ")" and? "Var a5: TestClass = TestClass (a1:" A ")", and the dictionary "items" "A1" and "a5" were treated as the same key even though they were added to "". This is because the Test class created as the above key uses "TestClass.a1.hashValue" for the key match check, and if it matches, it is implemented so that it is regarded as the same key. is.

Tuple

A tuple is a data type that is easier to handle than a structure and is a set of multiple values. A language specification that does not exist in Java. This can be useful, especially when dealing with a group of related values that you want to use temporarily, such as the return value of a function that returns the width and height of the screen size. The features are listed below.

--Tuples do not need to be defined in advance like structures. --Tuples cannot be extended with extensions like structures. --Tuples can be assigned and compared by pattern matching --Tuples can have anonymous members and can be managed by external names

Specify "var variable name: (type name, type name, type name ...)" in the declaration, and describe the types you want to manage as tuples in parentheses "()". It is also possible to set the initial value at the time of declaration as "var variable name: (type name, type name) = (value, value)". In addition, it is possible to give an external name to the members you want to combine, and it says "var variable name: (external name: type name, external name: type name) = (external name: value, external name: value)". Can be described as

python


var test1:(name:String, age:Int) //Can be easily understood by giving an external name
test1 = (name:"NYANKO", age:100)

print(test1.name) //You can also access using an external name
let test2:(String, Int) = ("WANKO", 2)  //It is possible to declare without giving an external name, and it can be assigned by pattern matching.

print(test2.1) //Index can be used when accessing
if (test2 == ("WANKO", 2)) { //Comparison by pattern matching is also possible
    print("same.")
}

Structure

Swift provides structures as an easy way to achieve encapsulation. It excels in managing simple data and is often used to represent data structures such as the return value of a function that returns the width and height of the screen size. At the time of definition, it is defined as "struct structure name {...}", and members are defined in the block of the structure. Declare "var structure variable name = structure ()" in the declaration. The structure has a default constructor, and it is also possible to initialize it as an external name during the initialization process by using the variable name of the member defined in the structure. The features are listed below.

--Structures need to be defined in advance before they can be used. --Structures can be extended with extensions. --Structures cannot be inherited. --Unlike a class, if it is assigned to a variable, it will be copied as a value.

Structures are similar in usability to classes, but the major difference from classes is that structs ≒ values.

Even if the class creates an instance and assigns it to "variable A" and another "variable B", the operation is performed on the instance. For example, the instance "Yoshiko" is sometimes "cleaning lady" variable A "" and sometimes "phantom thief mature woman fourteen" variable B "", but as "cleaning lady", breast augmentation at Takano Yuri Beauty Clinic. If you have surgery, the bust of "Phantom Thief Mature Woman Fourteen" will also increase. On the contrary, if the structure is assigned to "variable A'" and another "variable B'", it will be treated as a different value.

python


public class TestClass {
    var a1:String = ""
}

public class TestStruct {
    var a1:String = ""
}

var testStruct:TestClass = TestClass() //Declare structure
var testClass:TestClass = TestClass() //Declare an instance of the class
testStruct.a1 = "ABC"
testClass.a1 = "ABC"

var assignmentStruct = testStruct //Substitute structure
var assignmentClass = testClass //Assign an instance of the class

assignmentStruct.a1 = "DEF"
assignmentClass.a1 = "DEF"

print(testStruct.a1) //Because the structure is copied"ABC"Is output
print(testClass.a1) //Since the class is passed a reference, it is affected by the assignment destination."DEF"Is output

struct TestStruct {
    var a1:String = ""
}
class TestClass {
    var a1:String = ""  
}

Other comparison with Java

Type alias

Swift allows you to use existing types with aliases.

public typealias hoge1 = Int
public typealias hoge2 = (String, Int, Int)

var a1:hoge1 = 1
var a2:hoge2 = ("ABC", 1, 2)

print(a1)
print(a2)

Arithmetic expression

Java and Swift have the same notation for four arithmetic operations, and the comparison operator and increment / decrement notation are also the same, so if you are familiar with either one, you should be able to understand it without problems.

Control syntax

If statement

Java

python


int test = 1;
if (test == 1) {
    System.out.println("1");
} else if (test == 1) {
    System.out.println("2");
} else {?
    System.out.println("3");
}

Swift When describing a conditional expression, you may add parentheses as "(conditional expression)", but it is a general notation not to add it.

python


var test = 1;
if test == 1 {
    print("1")
} else if test == 1 {
    print("2")
} else {
    print("3")
}

Switch statement

Java

Java can only use char, byte, short, int, Character, Byte, Short, Integer, String (JDK 1.7 or later), or enum to evaluate switch statements. After processing the block of the case statement with the matching evaluation result, you can get out of the conditional branch of the switch by placing an explicit break statement. Therefore, if multiple evaluation values perform the same processing, break is not described.

python


int test = 1;
switch(test) {
    case 1:
    case 2:
        System.out.println("A");
        break;
    case 3:
        System.out.println("C");
        break;
    default:
        System.out.println("D");
}

Swift

Unlike Java, it is possible to set expressions and values (variables) in the evaluation target "switch (evaluation)", and to set character strings, expressions, etc. in addition to integers in the evaluation result "case evaluation value:". is. In addition, no explicit break statement is required, and if processing below the case statement of the matching evaluation result is performed, processing below the other case statements will not be performed. Therefore, if multiple evaluation values perform the same processing, describe the evaluation values in "case" separated by commas.

python


var test:Int = 1
switch test {
    case is Test:
        //If the type is Test
        print("A")
    case is Int:
        //If the type is Int
        print("B")
    case 1111, 2222:
        //If the value is 1111 or 2222
        //However, if the test type is not Int in the first place, "Expression pattern of type"'Int'cannot match values of type ~ ",
        print("C")
    default:
        print("D")
}

for statement

Java

The basic form is described as follows.

python


for (int i = 0; i < 10; i++) {
    System.out.println(i);
}

If you want to inspect the elements one by one, you can use the extended for statement. It can be used in instances of classes that implement the Iterable interface, arrays, and so on.

python


List<Integer> list = new ArrayList(); //Since List implements Iterable, extended for statement can be used.
for (Integer item : list) {
    System.out.println(i);
}

Swift

The basic form is described as follows.

python


for i in 0 ..< 10 {
    print(i)
}

If you want to inspect the elements one by one, you can use the extended for statement. It can be used for instances of classes that have an implementation of the SequenceType protocol, arrays, and so on.

python


for (item in 1..10) {
    print(i)
}

while statement

In the case of Swift, except that you can omit the parentheses as "(conditional expression)", Java and Swift have the same notation, so if you are familiar with either one, you can understand it without problems.

Function definition

Java

The notation when defining a function in Java is as follows.

python


//Access modifier Return type function name(Argument type Argument variable name) {
//return Return value;
// }
private int test(int value) {
    return value;
}

//How to call
test(1);

--If the return value does not exist, specify "void" for "Return type". --In Java, the return value cannot be tuple or multiple values, so the return value must be a primitive type (int, char, long, etc.) or an object type. --In Java, there is no "external name" of the argument in Swift, and when calling a function, it is necessary to pattern match by matching the type, number, and order of the argument of the defined function. --Since there is no default argument in Java, it is necessary to implement it by the telescoping method that creates multiple methods with different arguments.

Also, as a special note, in Java, the arguments passed to the function are not strictly passed by reference, but I think it is good to understand that the passed value can be manipulated inside the function function. For example, if you use it to re-instantiate inside a function, you will find that it is not actually passed by reference.

python


Test test = new Test();
test.a1 = "1";

Test newTest = newTest(test);

System.out.print(test); //1 is output
System.out.print(newTest); //null is output

private Test newTest(Test test) {
    test = new Test(); //A new reference is created
    test.a1 = "2";
    return test;
}

Also, in the case of immutable arguments, the caller's value does not change even if the argument value is manipulated in the function.

python


int value = 1;
test(value);
System.out.println(a); //1 is output

private void test(int value) {
    value = 2;
}

Swift

The notation when defining a function in Swift is as follows.

python


//func function name(External name Argument variable name:Argument type=Default value) ->Return type{
//return Return value;
// }
private func test(test value:Int = 9) -> Int {
    return value;
}

//How to call
test(test:1);

--If there is no return value, you can define a function that does not have a return value by specifying "Void" in "Return type" or omitting it. --In the case of Swift, it is possible to set multiple values for the return value by using tuples. --Since it is possible to give "external name" to the argument to Swift, you can specify "external name argument variable name: argument type" to improve readability. --Instead of explicitly specifying the external name as "external name argument variable name: argument type", it is also possible to specify "#" in the variable name such as "#argument variable name: argument type". --Since Swift3, the rule of function label has changed, and the external name is used as the argument variable name.

In Swift, the arguments passed to the function are passed by value, but there is a way to pass them by reference.

python


var a = 1
test(&a)
print(a) //The result is "2" because it was passed by reference.

func test(value:inout Int) {
    a = 2
}

Also, in Swift, functions can be treated as values. For example, the type information of a function that has one string argument and returns the return value of the string can be expressed as "(String)-> String".

python


let funcTest:(String)->String = test // func test(name:String) -> String {...}In funcTest
let message = funcTest("Swift") //Func test from the variable that stores the function(name:String) -> String {...}Call
print(message)

//function
func test(name:String) -> String {
    return "Hello" + name + "Mr."
}

You can also pass a function to a function because it can be treated as a value in Swift.

python


let funcTest:(String)->String = test // func test(name:String) -> String {...}In funcTest
callTest(name: "Java", function: funcTest) // callTest(name:String, function:(String)->String) {...}Call

//function
func test(name:String) -> String {
    return "Hello" + name + "Mr."
}

//Handed over test(name:String) ->A function that executes a String
func callTest(name:String, function:(String)->String) {
    let message = function(name) //Handed over test(name:String) ->Calling String
    print(message)  
}

It is also possible to define and use a function inside a function.

//Execution method
func exe() {
    let value = test(value1: 5, value2:3) //Function call
    print(value.0)
    print(value.1)
}
//A function that has a function inside
func test(value1:Int, value2:Int) -> (Int, Int) {
    //Internal function(1)
    func add(value1:Int, value2:Int) -> Int {
        return value1 + value2
    }
    //Internal function(2)
    func subtract(value1:Int, value2:Int) -> Int {
        return value1 - value2
    }
    
    let result1 = add(value1: value1, value2: value2) //Internal function(1)Get the result of
    let result2 = subtract(value1: value1, value2: value2) //Internal function(2)Get the result of
    
    return (result1, result2)
}

Anonymous and higher-order functions

Since Swift allows you to implement anonymous functions, you can also set anonymous functions in variables. Anonymous functions can be used without a function declaration (without giving a function name) and can be handled as follows.

python


// {(Argument name:Argument type name) -> (Return type name) in
//     //processing
//return Return value
// }

// (1)When there is no argument and no return value
let closure1 = {() -> () in
    print("test1")
}
closure1() // "test1"And output

// (2)No argument, return value String
let closure2 = {() -> String in
    return "test2"
}
print(closure2()) // "test2"And output
    
// (3)For arguments String, Int, return value String
let closure3 = {(param1:String, param2:Int) -> String in
    return param1 + param2.description
}
print(closure3("test", 3)) // "test3"And output
    
// (4)When using type inference at the time of calling without specifying the argument type In case of return value Int
let closures4:(String, Int) -> String
closures4 = {(param1, param2) -> String in
    return param1 + param2.description
}
print(closures4("test", 4)) // "test4"And output

You can pass function literals as function arguments. It is not necessary to declare separate functions, such as when you want to perform each processing according to the caller after executing the function processing declared as a function.

python


//Execution method
func exe() {
    //Triangle area calculation(Vertical x horizontal ÷ 2)In a variable as an anonymous function
    var calcTriangle = { (width:Int, height:Int) -> (Int) in
        return width * height / 2
    }
    //Rectangle area calculation(Vertical x horizontal)In a variable as an anonymous function
    var calcRctangle = { (width:Int, height:Int) -> (Int) in
        return width * height
    }
    print(calcAreaScreenRect(areaLogic: calcTriangle)) //Triangle area calculation Calls the area calculation function by screen size with an anonymous function as an argument
    print(calcAreaScreenRect(areaLogic: calcRctangle)) //Rectangle area calculation Call the area calculation function for each screen size with an anonymous function as an argument
}
///Area calculation by screen screen size
func calcAreaScreenRect(areaLogic:(Int, Int) -> (Int)) -> Int{
    let rect = UIScreen.main.bounds;
    return areaLogic(Int(rect.width), Int(rect.height))
}

Anonymous functions also have lexical scope characteristics that allow them to access the calling variable. Use anonymous function as an argument

python


var message = "Hello"
var printHello = {
    print(message) //Anonymous functions can access message
}
printHello() // "Hello"And output

As explained in the function declaration, you can use a function declared as an interval number as an argument, even if it is not an anonymous function. Such a function is called a higher-order function.

closure

Closure (function closure) is, in a nutshell, the definition of a function within a function. Specifically, it refers to a "function object realized by an anonymous function". Since anonymous functions can be used in Swift, closures can be used.

python


func getCounter()->()->Int {
    var counter = 0
    //Anonymous function
    let countUp = { ()->Int in
        counter += 1
        return counter
    }
    return countUp
}

In the above example, a function called "getCounter" is declared so that an anonymous function is defined internally and that function is returned. Calling this function has the following result:

python


let funcGetCounter:()-> Int = getCounter() //Anonymous function of getCounter return value

print(funcGetCounter()) // "1"Is output
print(funcGetCounter()) // "2"Is output
print(funcGetCounter()) // "3"Is output

Anonymous functions stored in "let funcGetCounter" are counted up each time they are called. In this way, the "var counter" in the function "getCounter" that the anonymous function refers to in the lexical scope is retained until there is no reference to "let funcGetCounter", and it can be used like an instance of a class.

Recommended Posts

Java and Swift comparison (2) Basic type / arithmetic expression / control syntax / function definition
Java and Swift comparison (1) Source control / Scope / Variables
[Java / Swift] Comparison of Java Interface and Swift Protocol
Java control syntax
Java control syntax
Java and Swift comparison (3) Class implementation / Class inheritance / Class design
About Java basic data types and reference type memory
[Java] String comparison and && and ||
[Java] Data type ①-Basic type
[Java] Control syntax notes
[Java] Difference between assignment of basic type variable and assignment of reference type variable
Same judgment / equal value judgment / comparison / order in Swift and Java
Java review ③ (control syntax [if / switch / while / for], conditional expression)
Java basic syntax + α trap
Basic data type and reference type
[Java] Type conversion speed comparison
Java class definition and instantiation
Java study # 7 (branch syntax type)
☾ Java / Iterative statement and iterative control statement
[Java] Summary of control syntax