programing

Swift의 읽기 전용 및 계산되지 않은 변수 속성

bestprogram 2023. 8. 30. 21:55

Swift의 읽기 전용 및 계산되지 않은 변수 속성

저는 새로운 애플 스위프트 언어로 뭔가를 알아내려고 합니다.목표-C에서 다음과 같은 작업을 수행했다고 가정해 보겠습니다.있습니다readonly속성을 개별적으로 변경할 수 없습니다.그러나 특정 방법을 사용하면 속성이 논리적으로 변경됩니다.

다음 예를 들어보겠습니다. 아주 간단한 시계입니다.저는 이것을 목표-C에 쓸 것입니다.

@interface Clock : NSObject

@property (readonly) NSUInteger hours;
@property (readonly) NSUInteger minutes;
@property (readonly) NSUInteger seconds;

- (void)incrementSeconds;

@end

@implementation Clock

- (void)incrementSeconds {
     _seconds++;

     if (_seconds == 60) {
        _seconds = 0;
        _minutes++;

         if (_minutes == 60) {
            _minutes = 0;
            _hours++;
        }
    }
}

@end

특정 목적을 위해 초, 분 및 시간을 직접 터치할 수 없으며, 방법을 사용하여 초 단위로 증분하는 것만 허용됩니다.이 방법만 인스턴스 변수의 트릭을 사용하여 값을 변경할 수 있습니다.

스위프트에는 그런 것이 없기 때문에 동등한 것을 찾으려고 합니다.이 작업을 수행할 경우:

class Clock : NSObject {

    var hours:   UInt = 0
    var minutes: UInt = 0
    var seconds: UInt = 0

    func incrementSeconds() {

        self.seconds++

        if self.seconds == 60 {

            self.seconds = 0
            self.minutes++

            if self.minutes == 60 {

                self.minutes = 0
                self.hours++
            }
        }
    }
}

그것은 효과가 있겠지만, 누구나 직접 속성을 변경할 수 있습니다.

아마도 나는 이미 오브젝티브-C에서 나쁜 디자인을 가지고 있었고 그것이 잠재적인 새로운 스위프트 동등물이 말이 되지 않는 이유입니다.만약 그렇지 않다면, 그리고 누군가 답을 가지고 있다면, 저는 매우 감사할 것입니다;)

애플이 약속한 미래의 접근 제어 메커니즘이 답이 아닐까요?

감사합니다!

속성 선언 앞에 다음과 같이 간단히 붙입니다.private(set)이와 같이:

public private(set) var hours:   UInt = 0
public private(set) var minutes: UInt = 0
public private(set) var seconds: UInt = 0

private소스 파일에 로컬로 유지하는 동안internal모듈/프로젝트에 대해 로컬로 유지합니다.

private(set)를 생성합니다.read-only속성, 반면private둘 다 설정합니다.set그리고.get비공개로

여러분이 원하는 것을 하는 두 가지 기본적인 방법이 있습니다.첫 번째 방법은 사유 재산과 해당 재산을 반환하는 공용 계산 재산을 갖는 것입니다.

public class Clock {

  private var _hours = 0

  public var hours: UInt {
    return _hours
  }

}

그러나 이것은 "스위프트 프로그래밍 언어" 의 "액세스 제어" 섹션에 명시된 것과 같이 다른 더 짧은 방법으로 달성될 수 있습니다.

public class Clock {

    public private(set) var hours = 0

}

참고로 공용 유형을 선언할 때 공용 이니셜라이저를 제공해야 합니다.모든 속성에 기본값을 제공하더라도,init()명시적으로 공개적으로 정의해야 합니다.

public class Clock {

    public private(set) var hours = 0

    public init() {
      hours = 0
    }
    // or simply `public init() {}`

}

이는 기본 이니셜라이저에 대해 설명할 때도 이 책의 동일한 섹션에 설명되어 있습니다.

액세스 제어 기능이 없으므로(발신자가 누구인지에 따라 다른 액세스 계약을 만들 수 없음을 의미) 다음과 같이 하십시오.

class Clock {
    struct Counter {
        var hours = 0;
        var minutes = 0;
        var seconds = 0;
        mutating func inc () {
            if ++seconds >= 60 {
                seconds = 0
                if ++minutes >= 60 {
                    minutes = 0
                    ++hours
                }
            }
        }
    }
    var counter = Counter()
    var hours : Int { return counter.hours }
    var minutes : Int { return counter.minutes }
    var seconds : Int { return counter.seconds }
    func incrementTime () { self.counter.inc() }
}

이것은 카운터에 대한 직접 액세스에 대한 간접적인 수준을 추가할 뿐입니다. 다른 클래스는 Clock을 만든 다음 해당 카운터에 직접 액세스할 수 있습니다.그러나 우리가 하려는 계약과 같은 아이디어는 다른 클래스가 클럭의 최상위 속성과 방법만 사용해야 한다는 것입니다.우리는 그 계약을 시행할 수 없지만, 사실 Objective-C에서도 시행이 거의 불가능했습니다.

실제로 액세스 제어(Swift에는 아직 존재하지 않음)는 목표 C에서 생각하는 것만큼 시행되지 않습니다.사람들이 정말 원한다면 읽기 전용 변수를 직접 수정할 수 있습니다.그들은 수업의 공개 인터페이스로 그것을 하지 않습니다.

Swift에서 유사한 작업을 수행할 수 있습니다(코드의 컷앤페이스트 및 일부 수정 사항 추가, 테스트하지 않았습니다).

class Clock : NSObject {

    var _hours:   UInt = 0
    var _minutes: UInt = 0
    var _seconds: UInt = 0

    var hours: UInt {
    get {
      return _hours
    }
    }

    var minutes: UInt {
    get {
      return _minutes
    }
    }

    var seconds: UInt  {
    get {
      return _seconds
    }
    }

    func incrementSeconds() {

        self._seconds++

        if self._seconds == 60 {

            self._seconds = 0
            self._minutes++

            if self._minutes == 60 {

                self._minutes = 0
                self._hours++
            }
        }
    }
}

실제 저장된 속성이 공용 인터페이스에 표시된다는 점을 제외하고는 목표 C에 있는 것과 동일합니다.

swift에서는 목표 C에서도 할 수 있는 더 흥미로운 것을 할 수 있지만, swift에서는 더 예쁠 것입니다(브라우저에서 편집했습니다, 테스트하지 않았습니다).

class Clock : NSObject {

    var hours: UInt = 0

    var minutes: UInt {
    didSet {
      hours += minutes / 60
      minutes %= 60
    }
    }

    var seconds: UInt  {
    didSet {
      minutes += seconds / 60
      seconds %= 60
    }
    }

    // you do not really need this any more
    func incrementSeconds() {
        seconds++
    }
}

언급URL : https://stackoverflow.com/questions/24081194/read-only-and-non-computed-variable-properties-in-swift