In general, the first program in a programming language tutorial should print "Hello, World" on the screen. In Swift, one line of code can be implemented:
println ("Hello, World")
If you write a C or objective-c code, you should be familiar with this form-in Swift, this line of code is a complete program. You do not need to import a separate library for input or output or string processing. 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 to write a semicolon at the end of each statement.
This tutorial will give you an initial understanding of Swift with a series of programming examples, and don't worry if you don't understand anything-any of the sections described in this chapter will be explained in more detail later in this chapter.
Note: To get the best experience, use the Code preview feature in Xcode. The Code preview feature lets you edit the code and see the results of the run in real time.
Simple values
Use let to declare constants, and use Var to declare variables. A constant value does not need to be fetched at compile time, but you can only assign it once. That means you can use represented to represent a value: You only have to decide once, but you need to use it many times.
- var myvariable = 42
- myvariable = 50
- Let myconstant = 42
The types of constants or variables must be the same as the values you assign to them. However, the declaration-time type is optional and the compiler automatically infers the type when the declaration is assigned at the same time. In the example above, the compiler infers that myvariable is an integer because its initial value is an integer.
If the initial value does not provide enough information (or 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 a constant, explicitly specifying a type of float and specifying an initial value of 4.
Values are never implicitly converted to other types. If you need to convert a value to another type, explicitly convert it.
- Let label = "the width is"
- Let width = 94
- Let Widthlabel = label + String (width)
Exercise: Delete The string from the last line, what is the error message?
There is a simpler way to convert a value to a string: write the value in parentheses, and write a backslash before the parentheses. For example:
- Let apples = 3
- Let oranges = 5
- Let applesummary = "I has \ (apples) apples."
- Let fruitsummary = "I had \ (apples + oranges) pieces of fruit."
Exercise: Use \ () to convert a floating-point calculation into a string, and add someone's name and say hello to him.
Use square brackets [] to create arrays and dictionaries, and use subscripts or keys 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 an empty array and an empty dictionary-just as you would declare a variable or pass arguments to a function.
- Shoppinglist = []//GO shopping and buy something
Control flow
Use if and switch to perform conditional operations, using for-in, for, while, and do-while for looping. Wrapping conditions and loop variable parentheses can be omitted, but curly braces on 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 an If statement, the condition must be a Boolean expression--like if score {...} This code is wrong.
You can use if and let together to handle the case of 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: What would it be to change optionalname to nil,greeting? Add an Else statement that assigns a different value to greeting when Optionalname is nil.
If the optional value of the variable is nil, the condition is judged to be false and the code in the curly braces is skipped. If it is not nil, the value is assigned to the constant behind let, so the value can be used in the code block.
Switch supports any type of data and various comparison operations-not just integers, but test equality.
- Let vegetable = "red pepper"
- Switch Vegetable {
- Case "Celery":
- Let vegetablecomment = "Add some raisins and make ants on a log."
- Case "cucumber", "watercress":
- Let vegetablecomment = "so would make a good tea sandwich."
- Case Let X where X.hassuffix ("Pepper"):
- Let vegetablecomment = "is it a spicy \ (x)?"
- Default
- Let vegetablecomment = "everything tastes good in soup."
- }
Exercise: Delete the default statement and see what is wrong with it?
After you run the clause that matches in the switch, the program exits the switch statement and does not continue running down, so you do not need to write a break at the end of each clause.
You can use for-in to traverse a dictionary, which requires two variables to represent each key-value pair.
- Let interestingnumbers = [
- "Prime": [2, 3, 5, 7, 11, 13],
- "Fibonacci": [1, 1, 2, 3, 5, 8],
- "Square": [1, 4, 9, 16, 25],
- ]
- var largest = 0
- For (kind, numbers) in Interestingnumbers {
- For number in numbers {
- If number > largest {
- largest = number
- }
- }
- }
- Largest
Exercise: Add another variable to record which type of number is the largest.
Use while to repeatedly run a piece of code until the condition is not met. The loop condition can be at the beginning as well as 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 it in loops: To represent a range, or to use a traditional notation, 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 created range does not contain an upper bound and needs to be used if you want to include ....
Functions and closures
Use Func to declare a function, using the name and arguments to invoke the function. Use to specify the function return value.
- Func greet (name:string, day:string), String {
- Return "Hello \ (name), today is \ (day)."
- }
- Greet ("Bob", "Tuesday")
Exercise: Remove the day parameter and add a parameter to indicate what lunch was eaten today.
Use a tuple to return multiple values.
- Func getgasprices () (double, double, double) {
- Return (3.59, 3.69, 3.79)
- }
- Getgasprices ()
The number of arguments to a function is variable, and an array is used to obtain them:
- Func sumof (Numbers:int ...), Int {
- var sum = 0
- For number in numbers {
- Sum + = number
- }
- return sum
- }
- Sumof ()
- Sumof (42, 597, 12)
Exercise: Write a function that calculates the mean of the parameter.
Functions can be nested. Nested functions can access variables of the outer function, and you can use nested functions to refactor a function that is too long or too complex.
- Func Returnfifteen (), Int {
- var y = ten func Add () {
- Y + = 5
- }
- Add ()
- Return y
- }
- Returnfifteen ()
A function is a class citizen, which means that the function can be the return value of another function.
- Func Makeincrementer ()-(int-int) {
- Func AddOne (number:int), Int {
- Return 1 + number
- }
- Return AddOne
- }
- var increment = Makeincrementer ()
- Increment (7)
Functions can also be passed as arguments to another function.
- Func hasanymatches (list:int[], condition:int-bool), BOOL {
- For item in list {
- If condition (item) {
- return True
- }
- }
- return False
- }
- Func Lessthanten (number:int), Bool {
- Return number < 10
- }
- var numbers = [20, 19, 7, 12]
- Hasanymatches (Numbers, Lessthanten)
function is actually a special kind of closure, you can use {} to create an anonymous closure. Use in to split the parameter and return the type.
- Numbers.map ({
- (Number:int), Int in
- Let result = 3 * number
- return result
- })
exercise: Rewrite closures, return 0 for all odd numbers.
There are many ways to create closures. If a type of closure is known, such as a callback function, you can ignore the type and return value of the parameter. A single statement closure will return the value of its statement as a result.
You can refer to parameters by parameter location instead of parameter name-this method is very useful in very short closures. When a closure is passed to a function as the last argument, it can be followed directly by the parentheses.
- Sort ([1, 5, 3, 2]) {$ > $}
Objects and classes
Use class and class names to create a class. The only difference between the declaration of a property in a class and a constant, variable declaration is that their context is a class. Similarly, methods and function declarations are the same.
- Class Shape {
- var numberofsides = 0
- Func simpledescription (), String {
- Return "A shape with \ (numberofsides) sides."
- }
- }
Exercise: Use let to add a constant property, and then add a method that receives a parameter.
To create an instance of a class, insert parentheses after the class name. Use point syntax to access the properties and methods of an instance.
- var shape = shape ()
- Shape.numberofsides = 7
- var shapedescription = shape.simpledescription ()
This version of the shape class lacks something important: a constructor to initialize the class instance. 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 differentiate instance variables. When you create an instance, pass in the parameters of the constructor to the class as if it were passed in as a function parameter. Each property needs to be assigned-whether it is declared (like numberofsides) or through a constructor (like name).
If you need to do some cleanup before deleting the object, create a destructor using Deinit.
Subclasses are defined by adding the name of the parent class after their class name, separated by a colon. You do not need a standard root class when creating a class, so you can ignore the parent class.
Subclass if you want to override the method of the parent class, you need to use the override tag--if you override the parent method without adding override, the compiler will error. The compiler will also detect if the override tag's 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 receives two parameters, one is the radius, one is the name, and the area and describe methods are implemented.
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 the setter of perimeter, the name of the new value is newvalue. You can display the settings after set a name.
Note that the constructor for the Equilateraltriangle class performs three steps:
- Set property values for a subclass declaration
- Calling the constructor of the parent class
- Changes the property value of the parent class definition. Other tasks such as calling methods, getters, and setters can also be done at this stage.
If you do not need to calculate a property but need to run some code before setting a new value, use Willset and Didset.
For example, the following class ensures that the side length of a triangle is always the same length as the sides of a square.
- Class Triangleandsquare {
- var Triangle:equilateraltriangle {
- Willset {
- Square.sidelength = Newvalue.sidelength
- }
- }
- var Square:square {
- Willset {
- Triangle.sidelength = Newvalue.sidelength
- }
- }
- Init (size:double, name:string) {
- Square = Square (sidelength:size, Name:name)
- Triangle = Equilateraltriangle (sidelength:size, Name:name)
- }
- }
- var triangleandsquare = Triangleandsquare (size:10, Name: "Another Test shape")
- TriangleAndSquare.square.sideLength
- TriangleAndSquare.triangle.sideLength
- Triangleandsquare.square = Square (sidelength:50, name: "Larger square")
- TriangleAndSquare.triangle.sideLength
There is an important difference between a method in a class and a general function, the parameter name of the function is used only inside the function, but the parameter name of the method needs to be explicitly stated at the time of the call (except for the first argument). By default, the parameter name of the method is the same as its name inside the method, but you can also define a second name, which is used inside the method.
- Class Counter {
- var count:int = 0
- Func IncrementBy (Amount:int, Numberoftimes times:int) {
- Count + = Amount * times
- }
- }
- var counter = counter ()
- Counter.incrementby (2, Numberoftimes:7)
When working with optional values for variables, you can add them before actions such as methods, properties, and sub-scripts. If the previous value is nil, then everything behind will be ignored and the entire expression returns nil. Otherwise, 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
Enumerations and struct bodies
Use an enum to create an enumeration. Just like the class and all other named types, enumerations can contain methods.
- Enum Rank:int {
- Case ACE = 1
- Case A, three, four, Five, Six, Seven, Eight, Nine, Ten
- Case Jack, Queen, King.
- Func simpledescription (), String {
- Switch Self {
- Case. Ace:
- Return "Ace"
- Case. Jack:
- Return "Jack"
- Case. Queen:
- Return "Queen"
- Case. King:
- Return "King"
- Default
- Return String (Self.toraw ())
- }
- }
- }
- Let Ace = Rank.ace
- Let Acerawvalue = Ace.toraw ()
Exercise: Write a function that compares two rank values by comparing their original values.
In the example above, the type of the enum original value is int, so you just need to set the first original value. The remaining raw values are assigned in order. You can also use a string or a floating-point number as the original value of the enumeration.
Use the Toraw and Fromraw functions to convert between the original value and the enumeration value.
- If Let Convertedrank = Rank.fromraw (3) {
- Let threedescription = Convertedrank.simpledescription ()
- }
The member value of an enumeration is an actual value and is not an alternative expression of the original value. In fact, if the original value doesn't make sense, you don't need to set it.
- Enum Suit {
- Case Spades, Hearts, Diamonds, Clubs
- Func simpledescription (), String {
- Switch Self {
- Case. Spades:
- Return "Spades"
- Case. Hearts:
- Return "Hearts"
- Case. Diamonds:
- Return "Diamonds"
- Case. Clubs:
- Return "clubs"
- }
- }
- }
- Let hearts = Suit.hearts
- Let heartsdescription = Hearts.simpledescription ()
Exercise: Add a color method to suit, return "black" to spades and clubs, and return "red" to Hearts and diamonds.
Note that there are two ways to refer to a Hearts member: When assigning a value to a Hearts constant, the enumeration member Suit.hearts needs to be referenced by its full name because the constant does not explicitly specify a type. In switch, enumeration members use abbreviations. Hearts to reference, because the value of self is already known to be a suit. You can use abbreviations in cases where the variable type is known.
Use a struct to create a struct body. Structs and classes have many of the same places, such as methods and constructors. One of the biggest differences between the structures is that the struct is a value, and the class is a reference.
- struct Card {
- var Rank:rank
- var suit:suit
- Func simpledescription (), String {
- Return "The \ (Rank.simpledescription ()) of \
- (Suit.simpledescription ()) "
- }
- }
- Let Threeofspades = Card (rank:. Three, suit:. Spades)
- Let threeofspadesdescription = Threeofspades.simpledescription ()
Exercise: Add a method to the card, create a full deck of cards, and match the rank and suit of each card.
An instance of an enumeration member can have an instance value. Instances of the same enumeration member can have different values. When you create an instance, the value is passed in. The instance value and the original value are different: The original value of the enumeration member is the same for all instances, and you are setting the original value when you define the enumeration.
For example, consider the time to get sunrise and sunset from the server. The server returns a normal result or error message.
- Enum Serverresponse {
- Case Result (String, String)
- Case Error (String)
- }
- Let success = Serverresponse.result ("6:00pm", "8:09 PM")
- Let failure = Serverresponse.error ("Out of cheese.")
- Switch Success {
- Case Let. Result (Sunrise, Sunset):
- Let Serverresponse = "Sunrise are at \ (Sunrise) and sunset are at \ (sunset)."
- Case Let. Error (Error):
- Let Serverresponse = "Failure ... \ (Error)"
- }
Exercise: Add a third case to serverresponse and switch.
Note How to extract the sunrise and sunset times from the Serverresponse.
Interfaces and extensions
Use protocol to declare an interface.
- Protocol Exampleprotocol {
- var simpledescription:string {Get}
- Mutating func adjust ()}
Classes, enumerations, and structs can all implement interfaces.
- Class Simpleclass:exampleprotocol {
- var simpledescription:string = "A very simple class."
- var anotherproperty:int = 69105
- Func Adjust () {
- Simpledescription + = "Now 100% adjusted."
- }
- }
- var a = Simpleclass ()
- A.adjust ()
- Let adescription = A.simpledescription
- struct Simplestructure:exampleprotocol {
- var simpledescription:string = "A simple structure" mutating func adjust () {
- Simpledescription + = "(adjusted)"
- }
- }
- var B = simplestructure ()
- B.adjust ()
- Let bdescription = B.simpledescription
Exercise: Write an enumeration that implements this interface.
Note When declaring simplestructure, the mutating keyword is used to mark a method that modifies a struct. The Simpleclass declaration does not need to tag any methods because the methods in the class often modify the class.
Use extension to add functionality to an existing type, such as adding a method that calculates a property. You can use extensions to add protocols to any type, even types that you import from external libraries or frameworks.
- Extension Int:exampleprotocol {
- var simpledescription:string {
- Return "the number \ (self)"
- }
- Mutating func adjust () {
- Self + = 42
- }
- }
- 7.simpleDescription
Exercise: Write an extension to the double type and add the Absolutevalue function.
You can use the interface name as you would with other named types-for example, to create a collection of objects that have different types but implement an interface. Methods that are defined outside the interface are not available when you are dealing with a type that is the value of an interface.
- Let Protocolvalue:exampleprotocol = A//Protocolvalue.anotherproperty
- Protocolvalue.simpledescription//Uncomment to see the error
Even though the type of the Protocolvalue variable runtime is simpleclass, the compiler will take its type as Exampleprotocol. This means that you cannot invoke a method or property that the class implements outside of the interface it implements.
Generic type
Write a name in angle brackets to create a generic function or type.
- Func repeat<itemtype> (Item:itemtype, Times:int), itemtype[] {
- var result = itemtype[] ()
- For I in 0..times {
- Result + = Item
- }
- return result
- }
- Repeat ("Knock", 4)
You can also create generic classes, enumerations, and struct-bodies.
- 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 the Where to specify a list of requirements after the type name-for example, to qualify a type that implements a protocol, you need to qualify two types to be the same, or to qualify a class that must have a specific parent class.
- Func anycommonelements <t, U where t:sequence, U:sequence, t.generatortype.element:equatable, T.GeneratorType.Eleme NT = = 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 with the contents of a common element of two sequences.
For simplicity, you can ignore where, just write the interface or class name after the colon. The <T:Equatable> and <t where t:equatable> are equivalent.
Swift Quick Start Tutorial: 30 minutes to play Swift