Attack on Swift-------------class and structure

Source: Internet
Author: User

classes and structs are a common and flexible construct that people use to build code. We can extend the functionality of classes and structs by using exactly the same syntax rules to define properties (constants, variables) and methods for classes and struct bodies.

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.

Attention
Typically an instance of a is called 对象 . 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 mainly use 实例 rather than 对象 .

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
    • Implement protocols to provide some standard functionality

For more information, see Properties, methods, subscript scripts, construction procedures, extensions, and protocols.

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

For more information, see Inheritance, type conversions, destructors, and automatic reference counting.

Attention
Structs are passed in the code in a copied way, without using reference counting.

Definition syntax

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

class SomeClass {    // class definition goes here}struct SomeStructure {    // structure definition goes here}

Attention
Each time you define a new class or struct, you are actually defining a new Swift type. So use UpperCamelCase this method to name (such as SomeClass and SomeStructure so on) in order to conform to the uppercase naming style of the standard Swift type ( String for example, Int and Bool ). Instead, use lowerCamelCase this method to name properties and methods (such as framerate and incrementCount ) so that they are distinguished from the type name.

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 Resolution struct named structure to describe the pixel resolution of a display. This struct contains two width height storage properties named and. A stored property is a constant or variable that is bundled and stored in a class or struct. When these two properties are initialized to integers 0 , they are inferred as Int types.

In the example above, we also defined a class named to VideoMode describe a particular pattern of a video display. This class contains four variable storage properties. The first is 分辨率 that it is initialized to an instance of a new Resolution struct, and the attribute type is inferred Resolution . The new instance also initializes the other three properties, namely, the initial value, the initial value, VideoMode false and the value is interlaced 0.0 frameRate optional String name . The name property is automatically assigned a default value, nil meaning "no name value" because it is an optional type.

Classes and struct-body instances

ResolutionVideoModethe definitions of structs and classes describe only 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 a pair of empty parentheses, such as or, after the type name of the struct or class Resolution() VideoMode() . 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 of an instance. The syntax rule is that the instance name is followed by the property name, and both are connected by a dot ( . ):

print("The width of someResolution is \(someResolution.width)")// 输出 "The width of someResolution is 0"

In the example above, the someResolution.width referenced someResolution width property returns width the initial value 0 .

You can also access child properties, such as properties in the properties VideoMode Resolution width :

print("The width of someVideoMode is \(someVideoMode.resolution.width)")// 输出 "The width of someVideoMode is 0"

You can also assign values to variable attributes using DOT syntax:

1280print("The width of someVideoMode is now \(someVideoMode.resolution.width)")// 输出 "The width of someVideoMode is now 1280"

Attention
Unlike the Objective-c language, Swift allows you to directly set child properties of a struct property. The last example above is to set the sub- someVideoMode resolution property of the property directly width , which does not require the new value to be set again for the entire 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

When a value type is assigned to a variable, constant, or passed to a function, its value is copied .

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 (Boolean), Strings (string), arrays (array), and dictionaries (dictionary) are all value types. And at the bottom are implemented in the form of structs.

In Swift, all structs and enum types 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 struct body in the previous example Resolution :

let hd = Resolution(width: 1920, height: 1080)var cinema = hd

In the example above, a constant named is declared hd , and its value is an instance initialized to full HD video resolution ( 1920 pixel width, 1080 high pixel) Resolution .

The example then declares a cinema variable named and hd assigns it to it. Because Resolution it is a struct, cinema the value is actually hd a copy copy, not hd itself. Although hd cinema they have the same width (width) and height (height), they are two completely different instances behind the scenes.

Below, in order to meet the demand for digital cinema screenings ( 2048 pixel width, 1080 high pixel), cinema the width properties need to be modified as follows:

cinema.width = 2048

Here, the property that will be displayed cinema width has been changed to 2048 :

print("cinema is now  \(cinema.width) pixels wide")// 输出 "cinema is now 2048 pixels wide"

However, the hd attributes in the initial instance width are 1920 :

print("hd is still \(hd.width) pixels wide")// 输出 "hd is still 1920 pixels wide"

When it hd is given cinema , it is actually copying the hd values stored in and then storing the copied data in the new cinema instance. The result is that two completely independent instances happen to contain the same values. Because they are independent of each other, they are cinema width modified to 2048 not affect the hd width values in.

Enumerations also follow the same Code of conduct:

enum CompassPoint {    case North, South, East, West}var currentDirection = CompassPoint.Westlet rememberedDirection = currentDirectioncurrentDirection = .Eastif rememberedDirection == .West { print("The remembered direction is still .West")}// 输出 "The remembered direction is still .West"

The value given in the above example rememberedDirection currentDirection is actually given a copy of the value. Values that are modified at the end of the assignment process currentDirection do not affect the copy of the rememberedDirection stored original value.

Class is a reference type

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

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

let tenEighty = VideoMode()tenEighty.resolution = hdtenEighty.interlaced = truetenEighty.name = "1080i"tenEighty.frameRate = 25.0

In the example above, a tenEighty constant named, which references a VideoMode new instance of a class, is declared. In the previous example, the video mode was given a copy of the HD resolution ( 1920 * 1080 ) (i.e., an hd instance). Also set to interlaced , named “1080i” . Finally, its frame rate is 25.0 frames per second.

Then, it tenEighty is given a alsoTenEighty new constant named, and the alsoTenEighty frame rate is modified:

let alsoTenEighty = tenEightyalsoTenEighty.frameRate = 30.0

Because a class is a reference type tenEight , alsoTenEight it is the same instance that is actually referenced VideoMode . In other words, they are two kinds of names for the same instance.

Below, by looking tenEighty at the frameRate properties, we will find that it correctly shows the VideoMode new frame rate of the referenced instance, with the value 30.0 :

print("The frameRate property of tenEighty is now \(tenEighty.frameRate)")// 输出 "The frameRate property of theEighty is now 30.0"

It is important to note that it is tenEighty alsoTenEighty declared as a constant instead of as a variable. However you can still change tenEighty.frameRate and alsoTenEighty.frameRate because the tenEighty alsoTenEighty values of these two constants have not changed. They do not "store" this VideoMode instance, but simply refer to the VideoMode instance. So, the value of the referenced property is changed instead of the VideoMode frameRate reference VideoMode constant.

Identity operator

Because a class is a reference type, there may be multiple constants and variables that reference the same class instance at the same time behind the scenes. (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. )

It would be helpful to be able to determine whether two constants or a variable references the same class instance. In order to achieve this, Swift has built two identity operators:

    • Equivalent to ( === )
    • The price is equal to ( !== )

Use these two operators to detect whether two constants or variables refer to the same instance:

if tenEighty === alsoTenEighty {    print("tenEighty and alsoTenEighty refer to the same Resolution instance.")}//输出 "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 "identical" and is judged to conform to the criteria defined by the designer, so this is a more appropriate term relative to "equality".

When you define your custom classes and structs, you are obligated to decide on the criteria for determining the "equality" of two instances. The process of implementing custom "equals" and "not equals" operators is described in detail in the chapter equivalence operator.

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 that references an instance of a reference type, similar to a pointer in the C language, but does not point directly to a memory address, nor does it 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. This means that the two apply different tasks. When you consider the data structure and function of a project, you need to decide whether each data structure is defined as a class or a struct.

As a general guideline, consider building a struct when one or more of the following conditions are met:

    • The main purpose of this data structure is to encapsulate a small number of related simple data values.
    • It is reasonable to expect that when an instance of the data structure is assigned or passed, the encapsulated data will be copied instead of referenced.
    • The value type attribute stored in the data structure should also be copied, not referenced.
    • The data structure does not need to inherit another property or behavior of an existing type.

For example, the following scenarios are appropriate for the use of structs:

    • The size of the geometry, encapsulating an width attribute and a height property, both Double types.
    • A path within a range that encapsulates a start property and length attribute, both of which are Int types.
    • In a three-dimensional coordinate system, a point, package x , y and z attribute, all of them 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 of String (string), array, and dictionary (Dictionary) types to replication behavior

In Swift, many basic types, such as String , Array and types, Dictionary are implemented in the form of structs. This means that when assigned to a new constant or variable, or passed into a function or method, their values are copied.

Objective-c NSString , NSArray and NSDictionary types are implemented in the form of classes, not structs. When they are assigned or passed into a function or method, no value copy occurs, but the reference to the existing instance is passed.

Attention
The above is a description of the "copy" behavior of strings, arrays, and dictionaries. In your code, the copy behavior seems to always happen. However, Swift performs the actual copy behind the scenes only when absolutely necessary. Swift manages all of the value copies to ensure performance optimization, so you don't have to avoid assigning values to ensure performance optimization.

Attack on Swift-------------class and structure

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.