Swift hello world! Swift quick start tutorial

  • 2020-05-07 20:31:09
  • OfStack

In general, the first program in a programming language tutorial should print "Hello, world" on the screen. In Swift, it can be implemented with 1 line of code:


println("hello, world")

If you've ever written C or Objective-C, you should be familiar with this form-in Swift, this line of code is a complete program. You do not need to import a single library for input/output or string handling. The code in the global scope is automatically used as the entry point for the program, so you don't need the main function. You also don't need a semicolon at the end of every statement.

This tutorial will give you an idea of Swift through a series of 1 programming examples, and don't worry if you don't understand anything -- anything covered in this chapter will be covered in more detail in the following sections.

Note: for the best experience, use the code preview feature in Xcode. The code preview feature lets you edit code and see the results in real time. Open Playground

simple value

Use let to declare constants and var to declare variables. The value of a constant is not acquired at compile time, but you can only assign it once. That is, you can express a value in terms of a constant: you only need to decide once, but you need to use it many times.


var myVariable = 42
myVariable = 50
let myConstant = 42

The type of a constant or variable must be the same as the value you assign it to. However, the type is optional when declared, and the compiler will automatically infer the type if the value is assigned at the same time as the declaration. In the above example, the compiler infers that myVariable is an integer (integer) because its initial value is an integer.

If the initial value does not provide enough information (or if there is no initial value), then you need to declare the type after the variable, separated by a colon.


let implicitInteger = 70
let implicitDouble = 70.0
let explicitDouble: Double = 70

Exercise: create 1 constant, explicitly specify the type as Float and specify an initial value of 4.

Values are never implicitly converted to other types. If you need to convert 1 value to another type, do the conversion explicitly.


let label = "The width is"
let width = 94
let widthLabel = label + String(width)

Exercise: delete String in the last line. What is the error?

There is an easier way to convert a value to a string: write the value in parentheses and write a backslash before the parentheses. Such as:


let apples = 3
let oranges = 5
let appleSummary = "I have \(apples) apples."
let fruitSummary = "I have \(apples + oranges) pieces of fruit."

Exercise: use \() to convert a floating point calculation to a string and add someone's name. Say hello.

Use square brackets [] to create arrays and dictionaries, and use subscripts or keys (key) to access elements.


var shoppingList = ["catfish", "water", "tulips", "blue paint"]
shoppingList[1] = "bottle of water" var occupations = [
    "Malcolm": "Captain",
    "Kaylee": "Mechanic",
]
occupations["Jayne"] = "Public Relations"

To create an empty array or dictionary, use the initialization syntax.

let emptyArray = String[]()
let emptyDictionary = Dictionary<String, Float>()

If the type information can be inferred, you can use [] and [:] to create empty arrays and empty dictionaries -- just as you would when declaring variables or passing arguments to functions.

shoppingList = []   // Go shopping and do some shopping

control flow

Use if and switch for conditional operations, and for-in, for, while, and do-while for loops. Wrap condition and loop variable braces can be omitted, but braces for the body of the statement are required.


let individualScores = [75, 43, 103, 87, 12]
var teamScore = 0
for score in individualScores {
    if score > 50 {
        teamScore += 3
    } else {
        teamScore += 1
    }
}
teamScore

In the if statement, the condition must be a Boolean expression -- like if score {... Code like} is wrong.

You can start with if and let to handle missing values. The values of some variables are optional. An optional value may be a specific value or nil, indicating that the value is missing. It is optional to add a question mark after the type to mark the value of the variable.


var optionalString: String? = "Hello"
optionalString == nil var optionalName: String? = "John Appleseed"
var greeting = "Hello!"
if let name = optionalName {
    greeting = "Hello, \(name)"
}

Exercise: change optionalName to nil, what will greeting be? Add 1 else statement when optionalName
It's nil and it assigns a different value to greeting.

If the variable's optional value is nil, the condition is judged to be false, and the code in braces is skipped. If it is not nil, the value is assigned to a constant following let so that the value can be used in the code block.

switch supports any type of data and various comparison operations -- not just integers and tests for equality.


var myVariable = 42
myVariable = 50
let myConstant = 42
0

Exercise: delete the default statement and see if there are any errors.

After running the matched clauses in switch, the program exits the switch statement and does not continue to run down, so there is no need to write break at the end of each clause.

You can use for-in to traverse the dictionary, requiring two variables to represent each key-value pair.


var myVariable = 42
myVariable = 50
let myConstant = 42
1

Exercise: add another variable to record which type of number is the largest.

Use while to run 1 piece of code repeatedly until the condition is not met. Loop conditions can be at the beginning or at the end.


var n = 2
while n < 100 {
    n = n * 2
}
n var m = 2
do {
    m = m * 2
} while m < 100
m

You can use.. in the loop. To express the scope, or use the traditional writing method, the two are equivalent:


var firstForLoop = 0
for i in 0..3 {
    firstForLoop += i
}
firstForLoop var secondForLoop = 0
for var i = 0; i < 3; ++i {
    secondForLoop += 1
}
secondForLoop

Use.. The scope created does not contain an upper bound. If you want to include it, you need to use... .

The function and the closure

Declare a function with func and call the function with its name and arguments. Use - > To specify the return value of the function.


var myVariable = 42
myVariable = 50
let myConstant = 42
4

Exercise: remove the day parameter and add a parameter to indicate what you had for lunch today.
Use 1 tuple to return multiple values.


var myVariable = 42
myVariable = 50
let myConstant = 42
5
The number of arguments of the function is variable. Use 1 array to get them:

var myVariable = 42
myVariable = 50
let myConstant = 42
6

Exercise: write a function that calculates the average value of a parameter.

Functions can be nested. Nested functions can access the variables of the outer function. You can use nested functions to refactor a function that is too long or too complex.


var myVariable = 42
myVariable = 50
let myConstant = 42
7

The function is equal to 1 citizen, which means that the function can be used as the return value of another function.


var myVariable = 42
myVariable = 50
let myConstant = 42
8
The function can also be passed in as an argument to another function.

var myVariable = 42
myVariable = 50
let myConstant = 42
9
The function is actually a special closure, and you can use {} to create an anonymous closure. Use in to split the parameter and return the type.

let implicitInteger = 70
let implicitDouble = 70.0
let explicitDouble: Double = 70
0

Exercise: override the closure to return 0 for all odd Numbers.

There are many ways to create closures. If the type of a closure is known, for example as a callback function, you can ignore the type and return value of the argument. A single statement closure returns the value of its statement as a result.

You can refer to parameters by their location rather than by their name -- this method is useful in very short closures. When a closure is passed to a function as the last argument, it can be followed directly by the parenthesis.

sort([1, 5, 3, 12, 2]) { $0 > $1 }

objects and classes

Use class and the class name to create a class. The only difference between the declaration of attributes in a class and the declaration of constants and variables is that their context is a class. The same goes for method and function declarations.


class Shape {
    var numberOfSides = 0
    func simpleDescription() -> String {
        return "A shape with \(numberOfSides) sides."
    }
}

Exercise: use let to add a constant property and a method to receive a parameter.

To create an instance of a class, put parentheses after the class name. Use the point syntax to access the properties and methods of the instance.


var shape = Shape()
shape.numberOfSides = 7
var shapeDescription = shape.simpleDescription()

This version of the Shape class is missing something important: a constructor to initialize an instance of the class. Use init to create a constructor.


class NamedShape {
    var numberOfSides: Int = 0
    var name: String     init(name: String) {
        self.name = name
    }     func simpleDescription() -> String {
        return "A shape with \(numberOfSides) sides."
    }
}

Note that self is used to distinguish between instance variables. When you create an instance, pass the constructor arguments to the class like function arguments 1. Each property needs to be assigned a value -- either by declaration (like numberOfSides) or by constructor (like name).

If you need to do some cleanup before deleting an object, use deinit to create a destructor.

Subclasses are defined by adding the name of the parent class after their class name, separated by a colon. You don't need a standard root class to create a class, so you can ignore the parent class.

Subclasses need to use the override flag if they want to override the parent method -- the compiler will report an error if they override the parent method without adding override. The compiler also checks to see if the override tagged method is actually in the parent class.


class Square: NamedShape {
    var sideLength: Double     init(sideLength: Double, name: String) {
        self.sideLength = sideLength
        super.init(name: name)
        numberOfSides = 4
    }     func area() ->  Double {
        return sideLength * sideLength
    }     override func simpleDescription() -> String {
        return "A square with sides of length \(sideLength)."
    }
}
let test = Square(sideLength: 5.2, name: "my test square")
test.area()
test.simpleDescription()

Exercise: create another subclass of NamedShape, Circle. The constructor accepts two parameters, one for radius and one for name. Implement the area and describe methods.
Properties can have getter and setter.


class EquilateralTriangle: NamedShape {
    var sideLength: Double = 0.0     init(sideLength: Double, name: String) {
        self.sideLength = sideLength
        super.init(name: name)
        numberOfSides = 3
    }     var perimeter: Double {
    get {
        return 3.0 * sideLength
    }
    set {
                sideLength = newValue / 3.0
    }
    }     override func simpleDescription() -> String {
        return "An equilateral triagle with sides of length \(sideLength)."
    }
}
var triangle = EquilateralTriangle(sideLength: 3.1, name: "a triangle")
triangle.perimeter
triangle.perimeter = 9.9
triangle.sideLength

In setter of perimeter, the name of the new value is newValue. You can display 1 name of Settings after set.

Notice that the constructor of the EquilateralTriangle class performs three steps:

1. Sets the value of the property declared by the subclass
2. Call the constructor of the parent class
3. Change the property value defined by the parent class. Other work such as calling methods, getters, and setters can also be done at this stage.

If you don't need to evaluate properties but need to run some code before setting a new value, use willSet and didSet.

For example, the following class ensures that the sides of a three-cornered shape are always the same as the sides of a square.


let implicitInteger = 70
let implicitDouble = 70.0
let explicitDouble: Double = 70
7

One important difference between a method in a class and a 1-like function is that the function's argument name is used only within the function, but the method's argument name needs to be explicitly stated when called (except for the first argument). By default, the method's parameter name is the same as its name inside the method, but you can also define a second name, which is used inside the method.


let implicitInteger = 70
let implicitDouble = 70.0
let explicitDouble: Double = 70
8

When working with the optional values of variables, you can add ? before the actions (such as methods, properties, and subscripts). . If the & # 63; The previous value was nil, ? Everything else is ignored, and the entire expression returns nil. Otherwise, the & # 63; Everything after that will be run. In both cases, the value of the entire expression is also an optional value.


let optionalSquare: Square? = Square(sideLength: 2.5, name: "optional square")
let sideLength = optionalSquare?.sideLength

enumeration and structure

Use enum to create an enumeration. Like classes and all other named types 1, enumerations can contain methods.


let label = "The width is"
let width = 94
let widthLabel = label + String(width)
0
Exercise: write 1 function and compare two Rank values by comparing their original values.
In the above example, the enumeration primitive value is of type Int, so you only need to set the first primitive value. The remaining original values are assigned in order. You can also use strings or floating point Numbers as the original values of an enumeration.

Use the toRaw and fromRaw functions to convert between the original and enumerated values.


let label = "The width is"
let width = 94
let widthLabel = label + String(width)
1
The member values of an enumeration are actual values and are not another representation of the original values. In fact, if the original value doesn't make sense, you don't need to set it.

let label = "The width is"
let width = 94
let widthLabel = label + String(width)
2
Exercise: add an color method to Suit, return "black" for spades and clubs, and "red" for hearts and diamonds.

Note that there are two ways to refer to an Hearts member: when assigning an hearts constant, the enumeration member Suit.Hearts needs to be referred to by its full name, because the constant does not explicitly specify a type. In switch, enumeration members are referred to using the abbreviation.Hearts, because the value of self is already known to be 1 suit. You can use abbreviations when you know the type of a variable.

Use struct to create a structure. Structs have a lot in common with classes, such as methods and constructors. One of the biggest differences between their structs is that structs are passed values and classes are passed references.


let label = "The width is"
let width = 94
let widthLabel = label + String(width)
3

Exercise: add a method to Card, create a full deck of playing CARDS and match rank and suit for each card.
An instance of an enumerated member can have an instance value. Instances of the same enumerated member can have different values. Just pass in the value when you create the instance. The instance value and the original value are different: the original value of the enumeration member is the same for all instances, and you set the original value when you define the enumeration.

For example, consider getting the time of sunrise and sunset from the server. The server returns either a normal result or an error message.


let label = "The width is"
let width = 94
let widthLabel = label + String(width)
4

Exercise: add a third case to ServerResponse and switch.

Note how to extract sunrise and sunset times from ServerResponse.

interface and extension

Declare an interface using protocol.


let label = "The width is"
let width = 94
let widthLabel = label + String(width)
5

Classes, enumerations, and structures can all implement interfaces.


let label = "The width is"
let width = 94
let widthLabel = label + String(width)
6

Exercise: write an enumeration that implements this interface.

Note that the mutating keyword is used to mark a method that modifies a structure when declaring SimpleStructure. SimpleClass's declaration does not need to flag any methods because methods in a class often modify the class.

Use extension to add functionality to an existing type, such as a method to calculate a property. You can use extensions to add protocols to any type, even the type you import from an external library or framework.


let label = "The width is"
let width = 94
let widthLabel = label + String(width)
7

Exercise: write an extension to the Double type to add absoluteValue functionality.

You can use the interface name as with any other named type 1 - for example, create a collection of objects that have different types but implement one interface. Methods defined outside the interface are not available when you are dealing with values of types that are interfaces.


let label = "The width is"
let width = 94
let widthLabel = label + String(width)
8

Even if the protocolValue variable runs of type simpleClass, the compiler treats its type as ExampleProtocol. This means that you cannot call methods or properties that a class implements outside of the interface it implements.

generic

Create a generic function or type by writing a name in Angle brackets.


let label = "The width is"
let width = 94
let widthLabel = label + String(width)
9
You can also create generic classes, enumerations, and structures.

// Reimplement the Swift standard library's optional type
enum OptionalValue<T> {
    case None
    case Some(T)
}
var possibleInteger: OptionalValue<Int> = .None
possibleInteger = .Some(100)

Use where after the type name to specify a list of requirements -- for example, to qualify the type that implements a protocol, you need to qualify both types to be the same, or a class must have a specific parent class.

func anyCommonElements <T, U where T: Sequence, U: Sequence, T.GeneratorType.Element: Equatable, T.GeneratorType.Element == U.GeneratorType.Element> (lhs: T, rhs: U) -> Bool {
    for lhsItem in lhs {
        for rhsItem in rhs {
            if lhsItem == rhsItem {
                return true
            }
        }
    }
    return false
}
anyCommonElements([1, 2, 3], [3])

Exercise: modify the anyCommonElements function to create a function that returns an array of common elements in two sequences.

For simplicity, you can ignore where and just write the interface or class name after the colon. < T: Equatable > and < T where T: Equatable > It's equivalent.


Related articles: