Swift Grammar learning and the like and struct

Source: Internet
Author: User
Tags class definition

Class and struct body

This page contains content:

Class and struct comparison
Structs and enumerations are value types
Class is a reference type
Selection of classes and structure bodies
Assignment and Replication behavior of collection (collection) types

Unlike other programming languages, Swift does not require you to create separate interfaces and implementation files for your custom classes and structs. All you have to do is define a class or struct in a single file, and the system will automatically generate external interfaces for other code.

Note: Typically an instance of a class is called an object. However, in swift, classes and structs are more closely related than in other languages, and most of the features discussed in this chapter can be used on classes and structs. Therefore, we will primarily use instances rather than objects.

Class and struct comparison

Classes and structs in Swift have a lot in common. The Common place is:

Defining properties for storing values
Define methods to provide functionality
Defining satellite scripts for accessing values
Defining constructors for generating initialization values
Extended to add functionality to the default implementation
Compliance with protocols to provide standard functionality for a class

Compared to structs, classes have the following additional functions:

Inheritance allows one class to inherit the characteristics of another class
Type conversions allow you to check and interpret the type of a class instance at run time
The destructor allows an instance of a class to release any resources it has been assigned
Reference count allows multiple references to a class

Note: Structs are passed through the code in a way that is copied, so do not use reference counting.
Defined

Classes and structs are defined in a similar way. We represent classes and structs by keyword class and struct, and define their specific contents in a pair of braces:

Class SomeClass {
Class definition goes here
}
struct Somestructure {
Structure definition goes here
}

Note: Each time you define a new class or struct, you are effectively defining a new Swift type. So use uppercamelcase this way to name (such as SomeClass and somestructure, etc.) in order to conform to the uppercase naming style of the standard swift type (such as String,int and BOOL). Instead, use Lowercamelcase to name properties and methods (such as framerate and incrementcount) so that they are distinguished from the class.
The following is an example of defining a struct and defining a class:

struct Resolution {
var width = 0
var height = 0
}
Class Videomode {
var resolution = Resolution ()
var interlaced = False
var framerate = 0.0
var name:string?
}

In the example above we define a struct named resolution, which describes the pixel resolution of a display. This structure contains two storage properties called width and height. A stored property is a constant or variable that is bundled and stored in a class or struct. When both properties are initialized to integer 0, they are inferred to be of type int.

In the example above, we also defined a class named Videomode that describes a particular pattern for a video display. This class contains four storage attribute variables. The first is the resolution, which is initialized to a new instance of the resolution struct, with the resolution property type. The new Videomode instance also initializes the other three properties, each of which is a interlaced with an initial value of false (meaning "non-interlaced video"). The playback frame rate initial value is 0.0 framerate and the value is the name of the optional string. The Name property is automatically assigned a default value of nil, meaning "No Name value" because it is an optional type.

Classes and struct-body instances

The definition of resolution struct and Videomode class only describes what is resolution and videomode. They do not describe a specific resolution (resolution) or video mode. To describe a particular resolution or video pattern, we need to generate an instance of them.

The syntax for generating struct and class instances is very similar:

Let someresolution = Resolution ()
Let Somevideomode = Videomode ()

Both structs and classes use the constructor syntax to generate new instances. The simplest form of constructor syntax is to follow an empty bracket, such as resolution () or Videomode (), after the type name of the struct or class. The properties of the class or struct instance created in this way are initialized to the default values. The construction process chapters discuss the initialization of classes and structs in more detail.

Property access

By using dot syntax (dot syntax), you can access the properties contained in the instance. The syntax rule is that the instance name is followed by the property name, both by the dot number (.). Connection:

Someresolution.width

You can also access child properties, such as the width property of the resolution property in Videomode:
SomeVideoMode.resolution.width
You can also assign a value to a property variable using dot syntax:

SomeVideoMode.resolution.width = 1280

Note: Unlike the Objective-c language, Swift allows you to set the child properties of a struct property directly. The last example above is to set the Somevideomode property of the resolution property directly, and the above operation does not need to reset the resolution property.
struct-type member-by-Constructor (memberwise initializers for structure Types)

All structs have an automatically generated member-by-constructor that initializes the properties of members in the new struct instance. The initial values for each property in the new instance can be passed to the member-by-constructor by the name of the property:

Let VGA = Resolution (width:640, height:480)

Unlike structs, class instances do not have a default member-by-constructor. The constructor is discussed in more detail in the Construction process section.

Structs and enumerations are value types

A value type is assigned to a variable, and the constant or itself is passed to a function, and the copy is actually manipulated.

In the previous chapters, we have used a lot of value types. In fact, in Swift, all the basic types: integers, floating-point numbers (floating-point), Boolean values (Booleans), strings (string), arrays (array), and dictionaries (dictionaries) are value types , and are implemented in the background in the form of structs.

In Swift, all structs and enumerations are value types. This means that their instances, as well as any value type attributes contained in the instance, are copied when passed in the code.

Take a look at the following example, which uses the resolution struct in the previous example:

Let HD = Resolution (width:1920, height:1080)
var cinema = HD

In the example above, a constant named HD is declared with a value of resolution instance initialized to full HD video resolution (1920 pixels wide and 1080 pixels high).

The example then declares a variable named cinema with a value of the previously declared HD. Because resolution is a struct, cinema's value is actually a copy of HD, not HD itself. Although HD and cinema have the same wide (width) and high (height) properties, they are two completely different instances in the background.

Below, in order to meet the demand for digital cinema screenings (2048 pixels wide and 1080 pixels high), cinema's width property needs to be modified as follows:

Cinema.width = 2048

Here, you will see that cinema's width property has been changed to 2048:

println ("Cinema is now (cinema.width) pixels wide")
Output "Cinema is now 2048 pixels wide"

However, the width attribute in the original HD instance is still 1920:

println ("HD is still (hd.width) pixels wide")
Output "HD is still 1920x1080 pixels wide"

When you assign HD to cinema, you actually copy the values stored in HD, and then store the copied data in a new cinema instance. The result is that two completely independent instances happen to contain the same values. Because they are independent of each other, changing the width of cinema to 2048 does not affect the width (width) in HD.

Enumerations also follow the same Code of conduct:

Enum CompassPoint {
Case North, South, East, West
}
var currentdirection = Compasspoint.west
Let remembereddirection = Currentdirection
Currentdirection =. East
if remembereddirection = =. West {
println ("The remembered direction is still. West ")
}
Output "The remembered direction is still. West "

In the example above, Remembereddirection is given the value of currentdirection, which is actually given a copy of the value. Modifying the value of the currentdirection after the assignment process ends does not affect the copy of the original value (value) stored by remembereddirection.

Class is a reference type

Unlike a value type, a reference type is referenced when assigned to a variable, constant, or passed to a function, and is not a copy. Therefore, the reference is made to the existing instance itself, not to its copy.

Take a look at the following example, which uses the Videomode class that was previously defined:

Let teneighty = Videomode ()
Teneighty.resolution = HD
Teneighty.interlaced = True
Teneighty.name = "1080i"
Teneighty.framerate = 25.0

In the example above, a constant named Teneighty is declared that references a new instance of the Videomode class. In the previous example, this video mode was given a copy (HD) of HD resolution (1920*1080). Also set to interleaved (interlaced), named "1080i". Finally, its frame rate is 25.0 frames per second.

The teneighty is then given a new constant named Alsoteneighty, while modifying the frame rate of the alsoteneighty:

Let alsoteneighty = Teneighty
Alsoteneighty.framerate = 30.0

Because the class is a reference type, teneight and Alsoteneight actually refer to the same Videomode instance. In other words, they are two kinds of names for the same instance.

Below, by looking at the Framerate property of Teneighty, we find that it correctly shows the new frame rate of the base Videomode instance with a value of 30.0:

println ("The Framerate property of Teneighty was now (teneighty.framerate)")
Output "The Framerate property of Theeighty was now 30.0"

It is important to note that Teneighty and Alsoteneighty are declared as constants ((constants) instead of variables. However, you can still change teneighty.framerate and alsoteneighty.framerate, because these two constants do not change themselves. They do not store the Videomode instance, which is simply a reference to the Videomode instance in the background. So, the change is the framerate parameter of the referenced base videomode, without changing the value of the constant.

Identity operator

Because a class is a reference type, there may be multiple constants and variables that reference a class instance at the same time in the background. (This is not true for structs and enumerations.) Because they are value types, their values are always copied when assigned to a constant, variable, or passed to a function. )

The identity operator determines whether a two constant or variable references the same class instance
Equivalent to (= = =)
Unequal to (!==)
These two operators are used to detect two constants or whether a variable refers to the same instance:

if teneighty = = = Alsoteneighty {
println ("Teneighty and Alsoteneighty refer to the same Resolution instance.")
}
Output "Teneighty and Alsoteneighty refer to the same Resolution instance."

Note that "equivalent to" (denoted by three equals, = = =) differs from "equals" (denoted by two equals, = =):

A constant or variable that is equivalent to a class type representing two classes is referring to the same class instance.
"Equals" means that the value of two instances is "equal" or "same", and it is a more appropriate term to be judged in accordance with the criteria defined by a Class designer definition.

When you define your custom classes and structs, you are obligated to decide on the criteria for determining the "equality" of two instances.
Pointer

If you have experience with c,c++ or objective-c language, then you might know that these languages use pointers to refer to addresses in memory. A Swift constant or variable referencing an instance of a reference type is similar to a pointer in C, but not directly to an address in memory, and does not require you to use an asterisk (*) to indicate that you are creating a reference. These references in Swift are defined in the same way as other constants or variables.

Selection of classes and structure bodies

In your code, you can use classes and structs to define your custom data types.

However, struct instances are always passed by value, and class instances are always passed by reference.
As a general guideline, consider building a struct when one or more of the following conditions are met:

The main purpose of the structure is to encapsulate a small number of related simple data values.
It is reasonable to expect that when an instance of a struct is assigned or passed, the encapsulated data will be copied instead of referenced.
Any value type attribute stored in the struct will also be copied, not referenced.
Structs do not need to inherit the properties or behaviors of another existing type.
Suitable structural candidates include:

The size of the geometry, which encapsulates a width property and a height property, both of which are double types.
A path within a range that encapsulates a start property and a length property, both of which are of type int.
A point within a three-dimensional coordinate system that encapsulates the X, Y, and Z Properties, all of which are double types.
In all other cases, define a class, generate an instance of it, and manage and pass it by reference. In practice, this means that the vast majority of custom data constructs should be classes, not structs.

Assignment and copy behavior of the set (Collection) type

The string, array, and dictionary (Dictionary) types in Swift are implemented in the form of structs. This means that when the String,array,dictionary type data is assigned to a new constant (or variable), or when it is passed into a function (or method), their values copy the behavior (the value is passed).

The objective-c string (nsstring), Array (Nsarray), and Dictionary (nsdictionary) types are implemented in the form of classes, which are different from the values passed in Swfit. Nsstring,nsarray,nsdictionary No value copy occurs when an assignment is made or passed into a function (or method), but rather a reference to an existing instance.

Note: The above is a description of the copy of the array, dictionary, string, and other values. In your code, the copy seems to have actually been generated where there is copy behavior. However, in the background of Swift, the actual (actual) copy will be executed only if it is necessary. Swift manages all of the value copies to ensure performance optimization, so there is no need to avoid assigning values to ensure optimal performance. (actual assignment is optimized by System management)

Swift Grammar learning and the like and struct

Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.