Latest web development tutorials

스위프트 계약

계약은 특정 기능에 필요한 메서드와 속성을 구현합니다.

계약의 타입의 요구 조건을 만족시킬 수는 추적 (일치) 계약으로 알려져있다.

클래스, 구조 또는 열거 유형의 프로토콜을 따라 프로토콜 정의 방법과 기능을 완료하기 위해 특정 구현을 제공 할 수 있습니다.

문법

다음과 같은 구문 계약은 다음과 같습니다 :

protocol SomeProtocol {
    // 协议内容
}

타입 정의의 일환으로 구분 : 프로토콜 클래스를 수행하려면 프로토콜 이름, 중간 콜론으로 이름을 입력해야합니다. 때 여러 프로토콜을 분리하여 각 프로토콜에 콤마 (,)로 구분하여, 수행합니다.

struct SomeStructure: FirstProtocol, AnotherProtocol {
    // 结构体内容
}

클래스가 부모 동안 프로토콜을 수행하는 경우, 부모 클래스 이름은 쉼표로 구분 프로토콜 이름 앞에 배치해야합니다.

class SomeClass: SomeSuperClass, FirstProtocol, AnotherProtocol {
    // 类的内容
}

등록 정보의 제공

프로토콜은 type 속성 메모리 또는 계산 속성을 지정하지 않고, 클래스 속성 또는 속성의 특정 인스턴스를 지정하는 데 사용됩니다. 또한 읽기 전용 또는 읽기 - 쓰기로 표시해야합니다.

계약은 보통 속성을 표현하기 위해 {설정 GET}를 추가 한 후 변수 var에 속성 유형 선언을 선언하는 읽기 전용 속성으로 표시하고, 읽고 쓸 수있다 {얻을}.

protocol classa {
    
    var marks: Int { get set }
    var result: Bool { get }
    
    func attendance() -> String
    func markssecured() -> String
    
}

protocol classb: classa {
    
    var present: Bool { get set }
    var subject: String { get set }
    var stname: String { get set }
    
}

class classc: classb {
    var marks = 96
    let result = true
    var present = false
    var subject = "Swift 协议"
    var stname = "Protocols"
    
    func attendance() -> String {
        return "The \(stname) has secured 99% attendance"
    }
    
    func markssecured() -> String {
        return "\(stname) has scored \(marks)"
    }
}

let studdet = classc()
studdet.stname = "Swift"
studdet.marks = 98
studdet.markssecured()

print(studdet.marks)
print(studdet.result)
print(studdet.present)
print(studdet.subject)
print(studdet.stname)

위의 프로그램 실행 출력은 다음과 같습니다

98
true
false
Swift 协议
Swift

돌연변이 조항의 방법

때때로 당신은 인스턴스 방법을 변경해야합니다.

예를 들어, 값 유형 (구조체 ENUM) 예에있어서, 프리픽스 함수로서 돌연변이 키워드,이 과정에 속하는 속성 수의 인스턴스의 값의 변형 예를 도시 FUNC 전에 기록.

protocol daysofaweek {
    mutating func show()
}

enum days: daysofaweek {
    case sun, mon, tue, wed, thurs, fri, sat
    mutating func show() {
        switch self {
        case sun:
            self = sun
            print("Sunday")
        case mon:
            self = mon
            print("Monday")
        case tue:
            self = tue
            print("Tuesday")
        case wed:
            self = wed
            print("Wednesday")
        case mon:
            self = thurs
            print("Thursday")
        case tue:
            self = fri
            print("Friday")
        case sat:
            self = sat
            print("Saturday")
        default:
            print("NO Such Day")
        }
    }
}

var res = days.wed
res.show()

위의 프로그램 실행 출력은 다음과 같습니다

Wednesday

생성자의 규정

계약은 지정된 생성자를 구현하는 사람들을 따라 그것을 필요로 할 수있다.

당신은 생성자가 계약의 정의에 성명을 쓴, 일반 생성자처럼 쓸 수 있지만, 다음과 같이 괄호 및 생성자 엔티티 구문은 쓰지 ​​않는다 :

protocol SomeProtocol {
   init(someParameter: Int)
}

protocol tcpprotocol {
   init(aprot: Int)
}

클래스 생성자 구현에 지정된 프로토콜

당신은 클래스의 계약 생성자를 수행하고 생성자 또는 클래스 생성자를 지정하는 것이 편리합니다 여부를 지정할 수 있습니다. 두 경우 모두, 당신은 생성자 첨자를 달성하기 위해해야 ​​수정 "을 요구"

class SomeClass: SomeProtocol {
   required init(someParameter: Int) {
      // 构造器实现
   }
}

protocol tcpprotocol {
   init(aprot: Int)
}

class tcpClass: tcpprotocol {
   required init(aprot: Int) {
   }
}

필요한 수정 보증을 사용하여 계약의 모든 서브 클래스를 따라, 또한 명시 적 구현을 ​​제공하거나 수행에 생성자를 상속 할 수 있습니다.

서브 클래스가 지정된 부모 클래스의 생성자를 오버라이드 (override), 생성자는 계약의 규정을 따르는 경우, 생성자 구현이 동시에 요구하고 재정의 수정을 표시해야합니다 :

protocol tcpprotocol {
    init(no1: Int)
}

class mainClass {
    var no1: Int // 局部变量
    init(no1: Int) {
        self.no1 = no1 // 初始化
    }
}

class subClass: mainClass, tcpprotocol {
    var no2: Int
    init(no1: Int, no2 : Int) {
        self.no2 = no2
        super.init(no1:no1)
    }
    // 因为遵循协议,需要加上"required"; 因为继承自父类,需要加上"override"
    required override convenience init(no1: Int)  {
        self.init(no1:no1, no2:0)
    }
}
let res = mainClass(no1: 20)
let show = subClass(no1: 30, no2: 50)

print("res is: \(res.no1)")
print("res is: \(show.no1)")
print("res is: \(show.no2)")

위의 프로그램 실행 출력은 다음과 같습니다

res is: 20
res is: 30
res is: 50

프로토콜 종류

계약 자체가 어떤 기능을 구현하지 않지만, 사용하는 프로토콜 형식으로 이용 될 수 있지만.

다른 프로토콜이 같은 일반적인 유형을 사용할 수 있습니다처럼 사용 시나리오 :

  • 함수, 메소드, 또는 생성자 매개 변수 유형 또는 반환 값 유형으로
  • 상수, 변수 또는 속성의 유형으로
  • 배열 사전 또는 다른 컨테이너 요소 유형으로

protocol Generator {
    typealias members
    func next() -> members?
}

var items = [10,20,30].generate()
while let x = items.next() {
    print(x)
}

for lists in [1,2,3].map( {i in i*5}) {
    print(lists)
}

print([100,200,300])
print([1,2,3].map({i in i*10}))

위의 프로그램 실행 출력은 다음과 같습니다

10
20
30
5
10
15
[100, 200, 300]
[10, 20, 30]

연장 계약에 구성원 추가

우리는 이미 (등 클래스, 구조체, 열거 형) 유형을 확장하고 확장 할 수 있습니다.

확장은 이미 존재하는 프로토콜 유형으로, 멤버 속성, 메서드 및 인덱스 스크립트를 추가 할 수 있습니다.

protocol AgeClasificationProtocol {
   var age: Int { get }
   func agetype() -> String
}

class Person {
   let firstname: String
   let lastname: String
   var age: Int
   init(firstname: String, lastname: String) {
      self.firstname = firstname
      self.lastname = lastname
      self.age = 10
   }
}

extension Person : AgeClasificationProtocol {
   func fullname() -> String {
      var c: String
      c = firstname + " " + lastname
      return c
   }
   
   func agetype() -> String {
      switch age {
      case 0...2:
         return "Baby"
      case 2...12:
         return "Child"
      case 13...19:
         return "Teenager"
      case let x where x > 65:
         return "Elderly"
      default:
         return "Normal"
      }
   }
}

상속 계약

프로토콜은 새로운 내용이 상속의 기준에 대한 합의를 필요로 추가 할 수 있습니다, 하나 이상의 다른 프로토콜을 상속 할 수 있습니다.

구문은 상속 및 다중 상속 된 계약 사이에 쉼표 (,)로 구분 클래스 상속 프로토콜과 유사합니다 :

protocol InheritingProtocol: SomeProtocol, AnotherProtocol {
    // 协议定义
}

protocol Classa {
    var no1: Int { get set }
    func calc(sum: Int)
}

protocol Result {
    func print(target: Classa)
}

class Student2: Result {
    func print(target: Classa) {
        target.calc(1)
    }
}

class Classb: Result {
    func print(target: Classa) {
        target.calc(5)
    }
}

class Student: Classa {
    var no1: Int = 10
    
    func calc(sum: Int) {
        no1 -= sum
        print("学生尝试 \(sum) 次通过")
        
        if no1 <= 0 {
            print("学生缺席考试")
        }
    }
}

class Player {
    var stmark: Result!
    
    init(stmark: Result) {
        self.stmark = stmark
    }
    
    func print(target: Classa) {
        stmark.print(target)
    }
}

var marks = Player(stmark: Student2())
var marksec = Student()

marks.print(marksec)
marks.print(marksec)
marks.print(marksec)
marks.stmark = Classb()
marks.print(marksec)
marks.print(marksec)
marks.print(marksec)

위의 프로그램 실행 출력은 다음과 같습니다

学生尝试 1 次通过
学生尝试 1 次通过
学生尝试 1 次通过
学生尝试 5 次通过
学生尝试 5 次通过
学生缺席考试
学生尝试 5 次通过
学生缺席考试

독점 계약

에만 카테고리 (클래스)에 적합 클래스 키워드 구속 계약을 추가하여, 프로토콜의리스트를 상속 입력.

클래스가 제 키워드 연속 프로토콜 목록에 나타날 수 있어야하고, 다른 후속 계약이다. 다음과 같은 형식은 다음과 같습니다

protocol SomeClassOnlyProtocol: class, SomeInheritedProtocol {
    // 协议定义
}

protocol TcpProtocol {
    init(no1: Int)
}

class MainClass {
    var no1: Int // 局部变量
    init(no1: Int) {
        self.no1 = no1 // 初始化
    }
}

class SubClass: MainClass, TcpProtocol {
    var no2: Int
    init(no1: Int, no2 : Int) {
        self.no2 = no2
        super.init(no1:no1)
    }
    // 因为遵循协议,需要加上"required"; 因为继承自父类,需要加上"override"
    required override convenience init(no1: Int)  {
        self.init(no1:no1, no2:0)
    }
}

let res = MainClass(no1: 20)
let show = SubClass(no1: 30, no2: 50)

print("res is: \(res.no1)")
print("res is: \(show.no1)")
print("res is: \(show.no2)")

위의 프로그램 실행 출력은 다음과 같습니다

res is: 20
res is: 30
res is: 50

합성 프로토콜

우리는 하나 이상의 프로토콜을 수행해야 할 때 매우 유용하다 스위프트 종합 지원 다중 프로토콜.

다음 구문은 다음과 같습니다

protocol<SomeProtocol, AnotherProtocol>

protocol Stname {
    var name: String { get }
}

protocol Stage {
    var age: Int { get }
}

struct Person: Stname, Stage {
    var name: String
    var age: Int
}

func show(celebrator: protocol<Stname, Stage>) {
    print("\(celebrator.name) is \(celebrator.age) years old")
}

let studname = Person(name: "Priya", age: 21)
print(studname)

let stud = Person(name: "Rehan", age: 29)
print(stud)

let student = Person(name: "Roshan", age: 19)
print(student)

위의 프로그램 실행 출력은 다음과 같습니다

Person(name: "Priya", age: 21)
Person(name: "Rehan", age: 29)
Person(name: "Roshan", age: 19)

일관성 검사 계약

사업자 프로토콜 준수를 확인하거나 특정 유형을 강요하는 것처럼 당신은 IS를 사용할 수 있습니다.

  • is 인스턴스가 있는지 여부를 확인하기 위해 연산자 遵循 특정 协议 .
  • as? 인스턴스가되는 옵션 값 반환 遵循 계약은 프로토콜 유형을 반환 할 때를, 그렇지 않으면 반환 nil .
  • as 필수 내리 뜬에 대한 강한 회전하는 경우, 런타임 오류가 발생합니다 실패합니다.

다음의 예는 HasArea 프로토콜은 두 번 유형 읽을 수있는 영역을 필요로 정의한다 :

protocol HasArea {
    var area: Double { get }
}

// 定义了Circle类,都遵循了HasArea协议
class Circle: HasArea {
    let pi = 3.1415927
    var radius: Double
    var area: Double { return pi * radius * radius }
    init(radius: Double) { self.radius = radius }
}

// 定义了Country类,都遵循了HasArea协议
class Country: HasArea {
    var area: Double
    init(area: Double) { self.area = area }
}

// Animal是一个没有实现HasArea协议的类
class Animal {
    var legs: Int
    init(legs: Int) { self.legs = legs }
}

let objects: [AnyObject] = [
    Circle(radius: 2.0),
    Country(area: 243_610),
    Animal(legs: 4)
]

for object in objects {
    // 对迭代出的每一个元素进行检查,看它是否遵循了HasArea协议
    if let objectWithArea = object as? HasArea {
        print("面积为 \(objectWithArea.area)")
    } else {
        print("没有面积")
    }
}

위의 프로그램 실행 출력은 다음과 같습니다

面积为 12.5663708
面积为 243610.0
没有面积