Swift2.0语言教程之类的属性

虽然函数可以简化代码,但是当一个程序中出现成百上千的函数和变量时,代码还是会显得很混乱。为此,人们又引入了新的类型——类。它是人们构建代码所用的一种通用、灵活的构造方式。本章将主要详细讲解类的使用。

Swift2.0语言的类与对象

类是一种新的数据类型,类似于生活中犬类、猫类等等。而对象则是将这个抽象的类进行了具体化。例如,在犬类中,有哈士奇,金毛等等,这些就是犬类的具体化,即对象。本节将讲解类的创建以及如何将类进行具体化(即实例化)为对象。

Swift2.0语言中类的组成

在一个类中通常可以包含如图8.1所示的内容。

 

图8.1  类的构成

其中,这些内容的功能如下:

  • q  属性:它将值和特定的类关联。
  • q  下标脚本:访问对象、集合等的快捷方式。
  • q  方法:实现某一特定的功能,类似于函数。

Swift2.0语言中创建类

在Swift中类的创建要比在Objective-C中简单的多。在Objecttive-C中,需要使用需要@interface和@end对类中的内容进行声明,还需要使用@implementation和@end对类声明的内容进行实现。在Xcode 6.3之前,它们需要放置在不同的文件中。虽然在Xcode 6.4中,它们可以放置在一个文件中,但是也相当的麻烦。Swift语言推出了自己创建类的方式,只使用一个class关键字,其一般的创建形式如下:

  • class 类名{
  • //具体内容
  • }

注意:在类中可以定义属性和方法,这些内容会在后面做详细的介绍。类名可以使用“大骆驼拼写法”方式来命名(如SomeClass),以便符合标准Swift 类型的大写命名风格(如String,Int和Bool)。对于后面所讲的对象、属性以及方法等可以使用“小骆驼拼写法”来命名。

【示例8-1】以下创建一个名为NewClass的类。代码如下:

  • class NewClass{
  • }

该类名称为NewClass。由于其中没有属性和方法,所以它只是一个空类。

Swift2.0语言实例化对象

实例化对象也可以称为类的实例,其语法形式如下:

  • var/let 对象名=类名()

【示例8-2】以下会创建一个类名为NewClass的类,然后再进行实例化。代码如下:

  • import Foundation
  • class NewClass{
  • }
  • let newClass=NewClass ()

注意:在进行实例化时,类名后一定要加上()。否则程序就会错误,如以下的代码:

  • var newClass = NewClass

由于在实例化时缺少了(),导致程序出现以下的错误信息:

  • Expected member name or constructor call after type name

以上所讲的这些只是简单的实例化对象。它使用了最简单的构造器来生成一个对象。在后面的章节中我们会为开发者讲解构造器的具体用法。

属性

在Objective-C中,属性是使用关键字@property关键字进行声明的内容。在Swift中,属性可以将值跟特定的类、结构或枚举关联。属性一般分为存储属性、计算属性和类型属性。本节将讲解对这些属性做详细的讲解。

Swift2.0语言存储属性

存储属性就是存储特定类中的一个常量或者变量。根据数据是否可变,分为常量存储属性和变量存储属性。

1.定义存储属性

常量存储属性使用let关键字定义(声明定义在一起进行,为了方便称为定义),其语法形式如下:

  • let 常量存储属性名:数据类型=初始值

变量存储属性可以使用var关键字定义,其语法形式如下:

  • var 变量存储属性名:数据类型=初始值

【示例8-3】以下代码定义类NewClass1,其中包含两个属性value1和value2,代码如下:

  • class NewClass1 {
  • let value1=20
  • var value2:Int=10
  • }

其中,value1使用let定义为常量存储属性,value2使用var定义为变量存储属性。在定义存储属性时,初始值是必不可少的,否则,就会出现错误。例如,以下的代码:

  • class NewClass1 {
  • let value1=20
  • var value2:Int
  • }

在此代码中,由于value2后面未加初始值,导致程序出现以下的错误信息:

  • Class 'NewClass1' has no initializers

2.访问存储属性

对于这些存储属性的访问,需要使用“.”点运算符。其语法形式如下:

  • 对象名.常量存储属性名/变量存储属性名

【示例8-4】以下定义了3个存储属性firstValue、secondValue、thirdValue,然后进行访问。代码如下:

  • import Foundation
  • class NewClass{
  • let firstValue:Int = 0
  • let secondValue=200
  • var thirdValue:String="Hello"
  • }
  • let newclass=NewClass()
  • //存储属性的访问
  • print("firstValue=\(newclass.firstValue)")
  • print("secondValue=\(newclass.secondValue)")
  • print("thirdValue=\(newclass.thirdValue)")

运行结果如下所示:

  • firstValue=0
  • secondValue=200
  • thirdValue=Hello

注意:对存储属性进行访问时,只可以对在自己类中定义的存储属性进行访问,否则就会出现错误,代码如下:

  • import Foundation
  • class NewClass1 {
  • var class1Value=10
  • }
  • class NewClass2 {
  • var class2Value=10
  • }
  • let newclass1=NewClass1()
  • print(newclass1.class1Value)
  • print(newclass1.class2Value)

在此代码中,由于class2Value存储属性是在NewClass2类中定义的,而不是NewClass1中定义的,所以程序就会出现以下的错误信息:

  • 'NewClass1' does not have a member named 'class2Value'

存储属性除了可以使用“.”点运算符进行读取外,还可以对其进行修改。修存储改属性的一般语法形式如下:

  • 对象名.存储属性=修改的内容

【示例8-5】以下代码就将secondValue的属性值"Hello"修改为了"Swift",代码如下:

  • import Foundation
  • class NewClass{
  • var secondValue:String="Hello"
  • }
  • let newclass=NewClass()
  • print("修改前:secondValue=\(newclass.secondValue)")
  • newclass.secondValue="Swift"                                                                       //修改存储实现
  • print("修改后:secondValue=\(newclass.secondValue)")

运行结果如下所示:

  • 修改前:secondValue=Hello
  • 修改后:secondValue=Swift

注意:只有变量存储属性才可以进行属性修改,常量存储属性不可以进行属性修改。如以下的代码:

  • import Foundation
  • class NewClass{
  • let firstValue:Int = 0
  • }
  • let newclass=NewClass()
  • print("修改前:firstValue=\(newclass.firstValue)")
  • newclass.firstValue=100                                                                 //试图对属性firstValue的值进行修改
  • print("修改后:\(newclass.firstValue)")

由于在类中使用了let对存储属性进行了定义,其值是不可以进行修改的,所以出现了以下的错误信息:

  • annot assign to 'let' property 'firstValue'

3.延迟存储属性

如果开发者只有在第一次调用存储属性时才能确定初始值,这时需要使用延迟存储属性实现。它的定义一般需要使用关键字lazy实现的,其语法形式如下:

  • lazy var 属性名:数据类型=初始内容

注意:在延迟存储属性中初始内容是不可以省去的。数据类型也是可以省去的,因为swift会根据初始内容自行判断数据类型。

【示例8-6】以下将使用lazy来定义一个延迟存储属性importer,代码如下:

  • import Foundation
  • class DataImporter {
  • var fileName = 123456
  • }
  • class DataManager {
  •  lazy var importer = DataImporter()
  • var data = [String]()
  • }
  • let manager = DataManager()
  • manager.data += ["Some more data"]
  • print(manager.data)
  • print(manager.importer.fileName)

在没有调用manager.importer.fileName时,实例的 importer属性还没有被创建。运行结果如下所示:

  • [Some more data]
  • 123456

我们可以使用断点调试的方法对此代码进行调试,来查看它的运行结果。具体步骤如下:

(1)为几行关键代码添加断点,并再添加一行代码,来查看添加importer的值,如图8.2所示。

 

图8.2  添加断点

(2)单击运行按钮,此时会在第一个断点处出现一个蓝色的箭头,表示此行代码在运行。然后选择Debug|Continue命令,按下调试窗口工具栏中的Continue program execution按钮,查看程序的执行,其中,可以使用查看器来观察属性值的变化。属性查看器位于调试信息窗口左半部分,如图8.3所示。程序的执行,如图8.4所示。其中,看到的self、data、importer.storage(因为importer是延迟属性,为了和其他属性区分,所以在查看器上看到是importer.storage)等都是属性。它们会随程序的执行为改变。

 

图8.3  查看器位置

 

图8.4  调试

在此图中程序执行到第3步,也就是第三个图时,类DataManager的属性data初始化,但没有给importer.storage属性进行初始化,一直为nil,直到执行到第7步,即第7个图时,才为importer.storage属性的属性初始化。

在定义一个延迟存储属性时需要注意以下2点,

(1)定义一个延迟存储属性时除了lazy外,还需要使用var关键字,但是不能使用let关键字,否则程序就会出现错误,如以下代码:

  • class DataImporter {
  • var fileName = 123456
  • }
  • class DataManager {
  •  lazy let importer = DataImporter()
  • var data = [String]()
  • }

由于在定义延迟属性时使用了let关键字,所以导致程序出现了以下的错误:

  • 'lazy' cannot be used on a let

(2)初始内容是不可以省去的,否则程序就会出现错误,如以下的代码,定义了一个没有初始值的延迟属性。代码如下:

  • class DataManager {
  • lazy var value:Int
  • }

由于在此代码中没有为value指定初始值,导致程序出现了以下的错误:

  • lazy properties must have an initializer

计算属性

除了存储属性外,类中还可以定义计算属性。计算属性不存储值,而是提供了一个getter和setter来分别进行获取值和设置其他属性的值。getter使用get关键字进行定义,其一般形式如下:

  • get{
  • return 某一属性值
  • }
  • setter使用set关键字进行定义,其一般语法形式如下:
  • set(参数名称){
  • 属性值=某一个值
  • }

当然,它也可以没有参数名称。这种情况会后面的内容中讲解。在计算属性中同时包含了getter和setter,其一般定义形式如下:

  • var 属性名:数据类型{
  • get{
  • return 某一属性值
  • }
  • set(参数名称){
  • 属性值=某一个值
  • }
  • }

【示例8-7】以下代码定义了一个类WalletClass,用来保存钱包中的金额,其默认单位为美元。为了方便用户以人民币为单位进行访问值和设置值,所以使用了计算属性cal。代码如下:

  • import Foundation
  • class WalletClass{
  • var money=0.0
  •  var cal:Double{                                                                                        //定义计算属性cal
  •         get{                                                                                            //定义getter
  •             let RMB=money*6.1
  •             return RMB                                                                  //返回以人民币为单位的金额
  •         }
  •         set(RMB){                                                                                 //定义setter
  •             money=RMB/6.1                                                         //返回以美元为单位的金额
  •         }
  •     }
  • }
  • var mywallet=WalletClass()
  • mywallet.cal=(20)
  • //输出
  • print(mywallet.cal)
  • print(mywallet.money)

运行结果如下所示:

  • 20.0
  • 3.27868852459016

注意:在使用计算属性时需要注意以下三点:

1.定义计算属性的关键字

在定义一个计算属性时,必须且只能使用var关键字,否则就会出现错误。以下的代码,将示例8-7的代码做了一些修改,代码如下:

  • class WalletClass{
  • var money=0.0
  • let cal:Double{
  • get{
  • var RMB=money*6.1
  • return RMB
  • }
  • set(RMB){
  • money=RMB/6.1
  • }
  • }
  • }

在此代码中定义一个计算属性,但是使用了let关键字,导致程序出现了以下的错误:

  • 'let' declarations cannot be a computed property

2.数据类型

在定义计算属性时,一定要为属性指定一个明确的数据类型,否则就会出现错误提示。例如以下的代码,是将示例8-7中的代码做了一些修改。代码如下:

  • class WalletClass{
  • var money=0.0
  • var cal{                                                                                                   //没有设置cal的数据类型
  • get{
  • var RMB=money*6.1
  • return RMB
  • }
  • set(RMB){
  • money=RMB/6.1
  • }
  • }
  • }

在此代码中由于没有为计算属性指定一个明确的数据类型,导致程序出现了以下的错误信息:

  • Computed property must have an explicit type
  • Type annotation missing in pattern

3.set后面的参数类型

在使用计算属性时,set后面的参数类型要和返回值的类型相同,不需要再指定类型。否则,程序就会出现错误。如以下的代码,此代码是将示例8-7中的代码做了一下修改,代码如下:

  • class WalletClass{
  • var money=0.0
  • var cal:Double{                                                                                               //没有设置cal的数据类型
  • get{
  • var RMB=money*6.1
  • return RMB
  • }
  • set(RMB:String){                                                                         //为参数定义了数据类型
  • money=RMB/6.1
  • }
  • }
  • }

在此代码中,对set后面的参数RMB指定了数据类型,导致程序出现了以下的错误:

  • Expected ')' after setter value name
  • Expected '{' to start setter definition

4.没有定义参数名称

如果计算属性的setter没有定义表示新值的参数名,则可以使用默认名称newValue。

【示例8-8】以下代码就使用了newValue来实现了华氏温度和摄氏温度的转换。代码如下:

  • import Foundation
  • class DegreeClass{
  • var degree=0.0
  • var cal :Double{
  • get{
  • let centigradedegree=(degree-32)/1.8
  • return centigradedegree
  • }
  • set{
  •   degree=1.8*newValue+32                                                 //没有定义参数名称,可以使用默认的
  • }
  • }
  • }
  • var degreeClass=DegreeClass()
  • degreeClass.cal=(10.0)
  • print(degreeClass.cal)
  • print(degreeClass.degree)

运行结果如下所示:

  • 10.0
  • 50.0

4.定义参数名后不能使用默认参数名

在set后面如果定义了参数名称,就不能再使用Swift默认的参数名称newValue。否则,就会导致程序出现错误。如以下的代码,将示例8-8做了一些修改,代码如下:

  • import Foundation
  • class DegreeClass{
  • var degree=0.0
  • var cal :Double{
  • get{
  • let centigradedegree=(degree-32)/1.8
  • return centigradedegree
  • }
  •  set(aaa){                                                                                                           //定义参数名称后,使用默认参数
  •             degree=1.8*newValue+32
  •         }
  • }
  • }

在此代码中,set后面定义了参数名称,但是又使用了默认的参数名称,导致程序出现了以下的错误:

  • Use of unresolved identifier 'newValue'

5.setter和getter的省略

在计算属性中,如果只有一个getter,则称为只读计算属性。只读计算属性可以返回一个值,但不能设置新的值。

【示例8-9】以下将通过getter来获取名称的字符串。代码如下:

  • import Foundation
  • class PersonName{
  • var name:String=""
  • var returnName :String{
  • if (name.isEmpty) {
  • return "NULL"
  • }else{
  • return name
  • }
  • }
  • }
  • var personClass=PersonName()
  • print("没有名字时\(personClass.returnName)")
  • personClass.name=("Tom")
  • print("有名字时\(personClass.returnName)")

在此代码中,当刚创建实例PersonName后,就去访问returnName。由于name默认为空,所以会返回字符串"NULL"。再对name赋值后,再一次访问returnName。由于name不为空,所以会返回name的内容。运行结果如下所示:

  • 没有名字时NULL
  • 有名字时Tom

注意:1.在只读计算属性中,可以将get关键字和花括号去掉。2.在C#等其他语言中可以将属性分为只读属性(只有getter)、只写属性(只有setter)和可读可写属性。但是在Swift中就不同了,只有只读计算属性和可读可写计算属性两个。没有只写计算属性,否则程序就会出现错误,如以下的代码:

  • class PersonName{
  • var name:String=""
  • var setName :String{
  • set{
  • }
  • }

在此代码中定义了一个只写计算属性,导致程序出现了以下的错误:

  • Variable with a setter must also have a getter

Swift2.0语言的类型属性

类型属性就是不需要对类进行实例化就可以使用的属性。它需要使用关键字class进行定义,其定义形式如下:

  • class var 类型属性名:数据类型{
  • 返回一个值
  • }

例如下面代码定义了一个类型属性count,代码如下:

  • class var count:Int{
  • return 20
  • }

类型属性也是可以被访问的,其访问类型属性的一般形式如下:

  • 类名.类型属性

【示例8-10】以下代码定义了一个类型属性newvalue,然后进行遍历访问该属性的每一个字符,并输出。代码如下:

  • import Foundation
  • class NewClass {
  • class var newvalue:String{                                                                  //定义类型属性newvalue
  • return "Hello"
  • }
  • }
  • print(NewClass.newvalue)
  • print("遍历NewClass.newvalue:")
  • //遍历类型属性newvalue的值
  • for index in NewClass.newvalue.characters {
  •     print(index)
  • }
  • 运行结果如下所示:
  • Hello
  • 遍历NewClass.newvalue
  • H
  • e
  • l
  • l
  • o

在使用类型属性时需要注意以下2点:

1.let关键字不能声明类型属性

定义类型属性时除了有关键字class外,还需要使用var关键字,但不能使用let关键字,否则程序提示错误,如以下代码,此代码定义了一个类型属性newvalue。代码如下:

  • import Foundation
  • class NewClass {
  • class let newvalue:Int{
  •         return 20
  •     }
  • }
  • print(NewClass.newvalue)

在此代码中使用了关键字let进行了类型属性的声明,导致程序出现了以下的错误:

  • 'let' declarations cannot be computed properties

2.存储属性

在类型方法中不能使用存储属性,否则程序就会出现错误,如以下的代码,此代码实现的是输出字符串"Hello"。

  • import Foundation
  • class NewClass {
  • var count:Int=20
  • class var newvalue:Int{
  •  return count
  • }
  • }
  • print(NewClass.newvalue)

其中,count是存储属性,newvalue是类型属性。在代码中,将str用在newvalue中,导致程序出现了以下的错误:

  • 'NewClass.Type' does not have a member named 'count'

3.对象不能访问类型属性

类型属性只可以使用类去访问,而不可以使用对象进行访问。否则,就会出现错误,如以下的代码:

  • import Foundation
  • class NewClass {
  • class var newvalue:Int{
  • return 20
  • }
  • }
  • var newClass=NewClass()
  • print(newClass.newvalue)

在此代码中,定义了一个类型属性newvalue,但在访问它时使用了对象,导致程序出现了以下错误:

  • 'NewClass' does not have a member named 'newvalue'

类型属性和存储属性一样,除了可以进行访问外,还可以进行修改,其语法形式如下:

  • 类名.类型属性=修改的内容

【示例8-11】以下程序将类型属性0变为200,并输出。代码如下所示:

  • import Foundation
  • var value:Int=0
  • class NewClass{
  • class var count :Int{
  • get{
  • let newvalue=value
  • return newvalue
  • }
  • set{
  • value=newValue
  • }
  • }
  • }
  • print("修改前:\(NewClass.count)")
  • NewClass.count=200
  • print("修改后:\(NewClass.count)")

运行结果如下所示:

  • 修改前:0
  • 修改后:200

Swift2.0语言中的属性监视器

属性监视器用来监控和响应属性值的变化。每次属性被设置值的时候,都会调用属性监视器,哪怕是新的值和原先的值相同。一个属性监视器由willSet和didSet组成,其定义形式如下:

  • var 属性名:数据类型=初始值{
  • willSet(参数名){
  • }
  • didSet(参数名){
  • }
  • }

其中,willSet在设置新的值之前被调用,它会将新的属性值作为固定参数传入。didSet在新的值被设置之后被调用,会将旧的属性值作为参数传入,可以为该参数命名或者使用默认参数名oldValue。

【示例8-12】以下将使用属性监视器监视totalSteps属性值的变化。代码如下:

  • import Foundation
  • class StepCounter {
  • var totalSteps: Int = 0 {
  • //完整的属性监视器
  •   willSet(newTotalSteps) {
  •             print("新的值为 \(newTotalSteps)")
  •         }
  •         didSet(old) {
  • if totalSteps > old {                                                                           
  •       print("与原来相比增减了 \(totalSteps - old) 个值")
  •             }
  •         }
  • }
  • }
  • let stepCounter = StepCounter()
  • stepCounter.totalSteps = 0
  • stepCounter.totalSteps = 200
  • stepCounter.totalSteps = 400
  • stepCounter.totalSteps = 800

运行结果如下所示:

  • 新的值为 0
  • 新的值为 200
  • 与原来相比增减了 200 个值
  • 新的值为 400
  • 与原来相比增减了 200 个值
  • 新的值为 800
  • 与原来相比增减了 400 个值

注意:在使用属性监视器时,需要使用注意以下4点:

1.不指定参数名

在willSet后面是可以不指定参数的,这时Swift会使用默认newValue表示新值。例如以下的代码在没有指定willSet参数的情况下,直接使用newValue来输出新的值。代码如下:

  • import Foundation
  • class StepCounter {
  • var totalSteps: Int=0  {
  • willSet {
  •  print("新的值为 \(newValue)")
  • }
  • didSet (old){
  • if totalSteps > old  {
  • print("与原来相比增减了 \(totalSteps - old) 个值")
  • }
  • }
  • }
  • }
  • let stepCounter = StepCounter()
  • stepCounter.totalSteps = 0
  • stepCounter.totalSteps = 200

运行结果如下所示:

  • 新的值为 0
  • 新的值为 200
  • 与原来相比增减了 200 个值

同样在didSet后面也可以不指定参数名,此时Swift会使用默认参数名oldValue。如以下的代码,此是示例8-12的代码做了一个修改,代码如下:

  • import Foundation
  • class StepCounter {
  • var totalSteps: Int = 0 {
  • //完整的属性监视器
  • willSet(newTotalSteps) {
  • print("新的值为 \(newTotalSteps)")
  • }
  • didSet {
  • if totalSteps > oldValue  {
  • print("与原来相比增减了 \(totalSteps - oldValue) 个值")
  • }
  • }
  • }
  • }
  • let stepCounter = StepCounter()
  • stepCounter.totalSteps = 0

2.默认参数不可以交换使用

在使用willSet和didSet时,它们默认的参数可以是不可以交换使用的。例如在willSet中使用的newValue不可以使用在didSet中,在didSet中使用的oldValue不可以使用在willSet中,否则程序就会出现错误。例如以下的代码,将示例8-12做了一些修改,代码如下:

  • import Foundation
  • class StepCounter {
  • var totalSteps: Int = 0 {
  • //完整的属性监视器
  • willSet {
  • print("新的值为 \(newValue)")
  • }
  • didSet {
  • if newValue > oldValue  {
  • print("与原来相比增减了 \(newValue - oldValue) 个值")   //输出新值和旧值之间的差值
  • }
  • }
  • }
  • }
  • let stepCounter = StepCounter()

在此代码中,由于在didSet中使用了willSet中的默认参数,导致程序出现了以下的错误:

  • Use of unresolved identifier 'newValue'

3.延迟属性不能使用属性监视器

在延迟属性中不可以使用属性监视器,否则程序会出现错误。如以下的代码:

  • class StepCounter {
  • lazy var totalSteps: Int=0  {
  • willSet {
  • print("新的值为 \(newValue)")
  • }
  • didSet {
  • if totalSteps > oldValue  {
  • print("与原来相比增减了 \(totalSteps - oldValue) 个值")
  • }
  • }
  • }
  • }

此代码中延迟属性中添加了属性监视器,导致程序出现了如下的错误:

  • lazy properties may not have observers

4.分开使用willSet和didSet

一个完整的属性监视器由willSet和didSet组成,但是willSet和didSet也可以单独使用。例如以下的代码就只使用了willSet输出了新值的信息。代码如下:

  • import Foundation
  • class StepCounter {
  • var totalSteps: Int=0  {
  • willSet {
  •             print("新的值为 \(newValue)")
  •         }
  • }
  • }
  • let stepCounter = StepCounter()
  • stepCounter.totalSteps = 0
  • stepCounter.totalSteps = 200
  • stepCounter.totalSteps = 600
  • stepCounter.totalSteps = 1200

这里属性监视器total只使用了willset,而没有使用didset。运作结果如下所示:

  • 新的值为 0
  • 新的值为 200
  • 新的值为 600
  • 新的值为 1200

本文选自:Swift2.0语言快速入门v3.0 大学霸内部资料,转载请注明出处,尊重技术尊重IT人!

Swift2.0语言教程之类的属性的更多相关文章

  1. Swift2.0语言教程之类的嵌套与可选链接

    Swift2.0语言教程之类的嵌套与可选链接 Swift2.0语言类的嵌套 在一个类中可以嵌套一个或者多个类.它们的嵌套形式也是不同的,大致分为了两种:直接嵌套和多次嵌套.下面依次讲解这两种方式. S ...

  2. Swift2.0语言教程之下标脚本

    Swift2.0语言教程之下标脚本 下标脚本 下标脚本是访问对象.集合或者序列的快速方式.开发者不需要调用实例特定的赋值和访问方法,就可以直接访问所需要的数值.例如在数组中,可以直接使用下标去访问或者 ...

  3. Swift2.0语言教程之类的方法

    Swift2.0语言教程之类的方法 Swift2.0语言的方法 方法其实就是函数,只不过它被定义在了类中.在Swift中,根据被使用的方式不同,方法分为了实例方法和类型方法两种.这两种方法的定义也和O ...

  4. Swift2.0语言教程之函数嵌套调用形式

    Swift2.0语言教程之函数嵌套调用形式 Swift2.0语言函数嵌套调用形式 在Swift中,在函数中还能够调用函数,从而形成嵌套调用.嵌套调用的形式往往有两种:一种是在一个函数中调用其它函数:还 ...

  5. Swift2.0语言教程之闭包

    Swift2.0语言教程之闭包 Swift2.0语言闭包 闭包是自包含的函数代码块,可以在代码中被传递和使用.Swift中的闭包与C和Objective-C中的代码块(blocks)以及其他一些编程语 ...

  6. Swift2.0语言教程之函数的返回值与函数类型

    Swift2.0语言教程之函数的返回值与函数类型 Swift2.0中函数的返回值 根据是否具有返回值,函数可以分为无返回值函数和有返回值函数.以下将会对这两种函数类型进行讲解. Swift2.0中具有 ...

  7. Swift3.0语言教程字符串转换为数字值

    Swift3.0语言教程字符串转换为数字值 Swift3.0语言教程字符串转换为数字值,在NSString中,开发者可以将字符串转换为数字值,通过这些数字值可以实现一些功能,如加法运算.减法运算等.数 ...

  8. Swift3.0语言教程使用URL字符串

    Swift3.0语言教程使用URL字符串 Swift3.0语言教程使用URL字符串,和路径一样,URL其实也是字符串,我们可以将这些字符串称为URL字符串.本小节将讲解URL字符串的使用. 1.编码 ...

  9. Swift3.0语言教程使用路径字符串

    Swift3.0语言教程使用路径字符串 Swift3.0语言教程使用路径字符串,路径其实是字符串的一种,我们称为路径字符串.本小节将讲解如何使用路径字符串. 1.组合路径 开发者可以将数组快速的组合成 ...

随机推荐

  1. 七牛云 上传图片 https 修改Nginx 注意事项

    仅在这记录下,今天的事情. 问题出自于Nginx 设置http 强制跳转 https设置 1.上午,出于某些需求,我将服务器Nginx 设置http 强行跳转 https server { liste ...

  2. CF 1008C Reorder the Array

    You are given an array of integers. Vasya can permute (change order) its integers. He wants to do it ...

  3. HDU 2058 The sum problem 数学题

    解题报告:可以说是一个纯数学题,要用到二元一次和二元二次解方程,我们假设[a,b]这个区间的所有的数的和是N,由此,我们可以得到以下公式: (b-a+1)*(a+b) / 2 = N;很显然,这是一个 ...

  4. 线段树区间更新(set暴力)

    题目链接:https://cn.vjudge.net/contest/66989#problem/I 具体思路:使用栈存储村庄被损坏的顺序,然后set存的是被损坏的村庄,然后每一次查询,直接找到要查询 ...

  5. oracle同义词是什么意思?

    相当于alias,比如把user1.table1 在user2中建一个同义词table1create synonym table1 for user1.table1;这样当我们在user2中查sele ...

  6. bzoj 3236: 洛谷 P4396: [AHOI2013]作业 (莫队, 分块)

    题目传送门:洛谷P4396. 题意简述: 给定一个长度为\(n\)的数列.有\(m\)次询问,每次询问区间\([l,r]\)中数值在\([a,b]\)之间的数的个数,和数值在\([a,b]\)之间的不 ...

  7. 诺贝斯特(厦门)电气有限公司http://www.thebest.cn.com/

    诺贝斯特(厦门)电气有限公司,公司位于厦门市湖里区塘边社168号.是一家专注于智能电网用户端智能配用电以及电气安全产品研发.生产和销售的高新技术企业:致力于为工矿企业.建筑楼宇以及基础设施等智能电网用 ...

  8. scp加端口号

    scp -P 21110 root@192.168.0.1:/home/abc.txt root@192.168.0.2:/root 注意: 参数-P 的位置一定要紧跟在scp命令后面 参数-P 指的 ...

  9. linux arm的存储分布那些事之一【转】

    转自:http://blog.csdn.net/xiaojsj111/article/details/11724081 linux arm的存储分布那些事之一 linux arm 内存分布总览 上图是 ...

  10. MySQL5.7之多源复制&Nginx中间件(上)【转】

    有生之年系列----MySQL5.7之多源复制&Nginx中间件(上)-wangwenan6-ITPUB博客http://blog.itpub.net/29510932/viewspace-1 ...