Latest web development tutorials

신속한 액세스 제어

액세스 제어는 코드 액세스 레벨에 소스 파일 또는 코드의 모듈 다른 정의 할 수 있습니다.

명시 적 액세스 레벨을 설정하는 하나의 종류 (클래스 구조체 ENUM)에, 또한 특성, 기능, 초기화에있어서, 기본형의 이러한 유형을 제공 할 수 있으며, 첨자 인덱스 액세스 레벨을 설정한다.

계약은 글로벌 상수, 변수와 함수의 계약을 포함, 특정 범위 내에서 사용하도록 제한 될 수 있습니다.

소스 파일과 기반 액세스 제어 모듈.

모듈 구축 및 프레임 워크 또는 응용 프로그램을 게시하기 위해 별도의 단위로 정의된다. 가져 오기 키워드에 스위프트에 사용할 수있는 모듈은 다른 모듈을 소개합니다.

소스 파일은 일반적으로 원본 파일이 여러 클래스와 함수를 정의 할 수있다 포함 된 모듈에 속하는 단일 소스 파일이다.

개인, 내부, 공공 : 스위프트 액세스 코드 엔티티의 세 가지 수준을 제공합니다.

액세스 수준 정의
공공의 소스 모듈의 파일에 액세스 할 수있는 임의의 엔티티는 다른 모듈의 도입을 통해 모든 엔티티의 소스 파일을 액세스 할 수있다.
내부의 : 소스 모듈의 파일에 액세스 할 수 있지만, 다른 소스 모듈 파일 엔티티에 액세스 할 수있는 임의의 개체.
개인 민간 단체로 알려진 현재의 소스 파일 만 엔티티를 사용합니다.

가장 진보 된 수준에 대한 공용 액세스는 개인 액세스의 가장 낮은 수준입니다.

문법

수정 공개, 내부, 개인 액세스 수준 엔티티를 선언함으로써 :

public class SomePublicClass {}
internal class SomeInternalClass {}
private class SomePrivateClass {}

public var somePublicVariable = 0
internal let someInternalConstant = 0
private func somePrivateFunction() {}

특별한 지시가없는 한, 그렇지 않으면 개체는 기본 액세스 수준은 내부 사용합니다.


기능 유형의 액세스

함수 산출 파라미터에 기초하여 액세스 레벨 함수의 리턴 형 액세스 레벨의 형식을 요구한다.

다음 예는 이름이 된 SomeFuncion 전역 함수를 정의하고, 명시 적으로 액세스 수준을 긍정하지 않습니다.

func someFunction() -> (SomeInternalClass, SomePrivateClass) {
    // 函数实现
}

클래스 SomeInternalClass 액세스 수준 중 하나의 기능은 다른 SomePrivateClass 액세스 레벨이 비공개 내부입니다. 따라서, 액세스 레벨 튜플의 원리에 따르면, 액세스 튜플 레벨 전용이다.

함수가 반환하기 때문에 액세스 수준의 유형은 개인 수정을 사용해야합니다 명시 적으로 함수를 선언, 비공개 :
private func someFunction() -> (SomeInternalClass, SomePrivateClass) {
    // 函数实现
}

이 기능은 공용 또는 내부로 선언 또는 내부 액세스 수준이 잘못 기본값을 사용합니다.


액세스 열거 형

액세스 수준 열거 회원 열거에서 상속, 당신은 액세스 별도의 선언 다른 수준의 멤버를 열거 할 수 없습니다.

예를 들어, 예 다음, 열거 학생은 명시 적으로 다음 액세스의 마크 수준은 공공 회원 이름이며, 공공 레벨로 선언 :

public enum Student {
    case Name(String)
    case Mark(Int,Int,Int)
}

var studDetails = Student.Name("Swift")
var studMarks = Student.Mark(98,97,95)

switch studMarks {
case .Name(let studName):
    print("学生名: \(studName).")
case .Mark(let Mark1, let Mark2, let Mark3):
    print("学生成绩: \(Mark1),\(Mark2),\(Mark3)")
}

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

学生成绩: 98,97,95

서브 클래스 액세스

액세스 수준 하위 클래스는 상위 클래스의 액세스 수준을 초과하지 않아야한다. 예를 들어, 상위 클래스의 액세스 레벨은 내부에 상기 서브 클래스의 액세스 레벨 공용으로 선언 될 수 없다.

public class SuperClass {
    private func show() {
        print("超类")
    }
}

// 访问级别不能低于超类 internal > public
internal class SubClass: SuperClass  {
    override internal func show() {
        print("子类")
    }
}

let sup = SuperClass()
sup.show()

let sub = SubClass()
sub.show()

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

超类
子类

상수, 변수, 속성, 인덱스 액세스

상수, 변수, 속성은 액세스 수준의 자신의 종류 이상을 가질 수 없습니다.

예를 들어, 공용 속성의 레벨을 규정하지만, 컴파일러가 허용되지 않는 수준의 개인의 유형이다.

마찬가지로, 인덱스는 인덱스 유형 또는 액세스 레벨 유형보다 높은 수익을 가질 수 없다.

상수는 변수, 속성, 첨자 인덱스 정의 유형은 개인 수준, 그들은 분명 개인에 대한 액세스 수준을 언급해야하는 경우 :

private var privateInstance = SomePrivateClass()

getter 및 setter 액세스

게터와 세터 액세스 수준 상수, 변수, 속성, 첨자 지수는 구성원에 속하는 액세스 수준에서 상속.

만약 변수, 특성을 조절하거나 첨자 인덱스가 읽기 및 쓰기 권한 있도록 세터 액세스 레벨은 게터 대응하는 액세스 레벨보다 낮을 수있다.

class Samplepgm {
    private var counter: Int = 0{
        willSet(newTotal){
            print("计数器: \(newTotal)")
        }
        didSet{
            if counter > oldValue {
                print("新增加数量 \(counter - oldValue)")
            }
        }
    }
}

let NewCounter = Samplepgm()
NewCounter.counter = 100
NewCounter.counter = 800

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

计数器: 100
新增加数量 100
计数器: 800
新增加数量 700

생성자와 기본 생성자 액세스

초기화

우리는 액세스 레벨을 선언 초기화 방법을 정의 할 수 있지만, 다른 클래스 나 접속의 높은 레벨에 속한다. 그러나 필요한 생성자 예외는 그들의 클래스의 동일한 레벨로 레벨 액세스를 액세스한다.

함수 또는 메소드 파라미터로서, 액세스 레벨 초기화 파라미터 방법은 액세스 레벨 초기화 방법보다 작을 수 없다.

기본 초기화 방법

스위프트는 클래스 할당을 제공하기 위해 자신의 재산 모두를 위해, 매개 변수없이 기본 초기화 방법을 제공하지만, 특정 값을 제공하지 않는 구조이다.

디폴트 초기화 방법은, 동일한 수준의 액세스 및 액세스 레벨의 유형에 속한다.

각 서브 클래스의 액세스 () init 메소드 전에 필요한 키워드 문을 사용합니다.

class classA {
    required init() {
        var a = 10
        print(a)
    }
}

class classB: classA {
    required init() {
        var b = 30
        print(b)
    }
}

let res = classA()
let show = classB()

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

10
30
10

액세스 계약

당신이 명확한 합의가 액세스 수준을 긍정하려는 경우, 우리는 당신이 동의 만하면 도메인을 언급 액세스 레벨 역할에 사용되는 있는지 확인하려면주의해야합니다.

공용 액세스 레벨 프로토콜을 정의하는 경우, 그것은 공공 액세스 수준에서 제공되는 계약의 필요한 기능을 달성했다. 이는 공중 액세스 레벨을 다른 유형의 내부의 부재에 대한 액세스 레벨과 같은 다른 형태와 다르다.

public protocol TcpProtocol {
    init(no1: Int)
}

public class MainClass {
    var no1: Int // local storage
    init(no1: Int) {
        self.no1 = no1 // initialization
    }
}

class SubClass: MainClass, TcpProtocol {
    var no2: Int
    init(no1: Int, no2 : Int) {
        self.no2 = no2
        super.init(no1:no1)
    }
    
    // Requires only one parameter for convenient method
    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

확장 액세스

당신은 조건 클래스, 구조, 열거 확장을 허용 할 수 아래. 일본어 반원 연장 부재는 동일한 액세스 레벨을 가져야한다. 예를 들어, 당신은 원래 기본 내부 액세스 수준의 동일한 구성원이 있어야 새로운 멤버를 추가, 일반적인 유형을 확장합니다.

모든 구성원이 새 기본 액세스 수준을 긍정에 또는 명시 적으로 확장 내에서 (예 : 개인 확장의 사용 등) 액세스의 확장 수준을 선언 할 수 있습니다. 새 기본 액세스 수준은 여전히 ​​액세스 수준이 적용 개별 구성원을 긍정 할 수 있습니다.


일반 액세스

액세스 수준 제네릭 형식 또는 일반 기능은 일반 유형, 함수 자체 액세스의 세 가장 낮은 수준의 제네릭 형식 매개 변수를 사용합니다.

public struct TOS<T> {
    var items = [T]()
    private mutating func push(item: T) {
        items.append(item)
    }
    
    mutating func pop() -> T {
        return items.removeLast()
    }
}

var tos = TOS<String>()
tos.push("Swift")
print(tos.items)

tos.push("泛型")
print(tos.items)

tos.push("类型参数")
print(tos.items)

tos.push("类型参数名")
print(tos.items)
let deletetos = tos.pop()

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

["Swift"]
["Swift", "泛型"]
["Swift", "泛型", "类型参数"]
["Swift", "泛型", "类型参数", "类型参数名"]

유형 별칭

사용자가 아무것도 입력 별칭은 액세스 제어를 용이하게하기 위해, 다른 형식으로 정의한다. 타입 별명 타입의 액세스 레벨 액세스 원래 수준보다 높을 수 없다.

예를 들어, 개인 클래스 타입 별칭은 공공 내부 전용 형에 할당 될 수 있지만, 공개 레벨 타입 별칭은 내부 또는 개인 레벨 유형으로 설정 될 수없는 공개 레벨 유형으로 설정 될 수있다 .

참고 :이 규칙은 또한 관련 유형 이름과 별명을 프로토콜 적합성을 충족하기 위해 경우에 적용됩니다.

public protocol Container {
    typealias ItemType
    mutating func append(item: ItemType)
    var count: Int { get }
    subscript(i: Int) -> ItemType { get }
}

struct Stack<T>: Container {
    // original Stack<T> implementation
    var items = [T]()
    mutating func push(item: T) {
        items.append(item)
    }
    
    mutating func pop() -> T {
        return items.removeLast()
    }
    
    // conformance to the Container protocol
    mutating func append(item: T) {
        self.push(item)
    }
    
    var count: Int {
        return items.count
    }
    
    subscript(i: Int) -> T {
        return items[i]
    }
}

func allItemsMatch<
    C1: Container, C2: Container
    where C1.ItemType == C2.ItemType, C1.ItemType: Equatable>
    (someContainer: C1, anotherContainer: C2) -> Bool {
        // check that both containers contain the same number of items
        if someContainer.count != anotherContainer.count {
            return false
        }
        
        // check each pair of items to see if they are equivalent
        for i in 0..<someContainer.count {
            if someContainer[i] != anotherContainer[i] {
                return false
            }
        }
        
        // all items match, so return true
        return true
}

var tos = Stack<String>()
tos.push("Swift")
print(tos.items)

tos.push("泛型")
print(tos.items)

tos.push("Where 语句")
print(tos.items)

var eos = ["Swift", "泛型", "Where 语句"]
print(eos)

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

["Swift"]
["Swift", "泛型"]
["Swift", "泛型", "Where 语句"]
["Swift", "泛型", "Where 语句"]