IT이야기

문자열의 차이점

cyworld 2021. 10. 23. 09:50
반응형

문자열의 차이점은 무엇입니까? 그리고 스트링! (선택적 변수를 만드는 두 가지 방법)?


에서 스위프트 언어 프로그래밍 (?) : 나는 당신이 두 가지 방법으로 옵션 변수를 만들 수 있습니다 읽었습니다 (애플의 책) (!) 물음표를 사용하거나 느낌표를 사용하여합니다.

차이점은 (?)로 옵셔널의 값을 얻을 때 값을 원할 때마다 느낌표를 사용해야 한다는 것입니다.

var str: String? = "Question mark?"
println(str!) // Exclamation mark needed
str = nil    

(!)가 있는 동안 접미사 없이 얻을 수 있습니다.

var str: String! = "Exclamation mark!"
println(str) // No suffix needed
str = nil

차이점은 무엇이며 차이가 전혀 없다면 왜 2가지 방법이 있습니까?


암시적으로 래핑되지 않은 옵션(!로 선언됨)을 사용할 때의 진정한 이점은 두 클래스가 서로를 가리키고 강력한 참조 주기를 피해야 할 때 클래스 초기화와 관련이 있다는 것입니다. 예를 들어:

클래스 A <-> 클래스 B

클래스 A의 초기화 루틴은 클래스 B를 생성(및 소유)해야 하고 B는 A에 대한 약한 참조가 필요합니다.

class A {
    let instanceOfB: B!
    init() {
        self.instanceOfB = B(instanceOfA: self)
    }
}

class B {
    unowned let instanceOfA: A
    init(instanceOfA: A) {
        self.instanceOfA = instanceOfA
    }
}

지금,

  • 클래스 B는 초기화하려면 클래스 A에 대한 참조가 필요합니다.
  • 클래스 A는 self완전히 초기화된 후에 클래스 B의 이니셜라이저에 전달할 수 있습니다 .
  • instanceOfB따라서 클래스 B가 생성되기 전에 클래스 A가 초기화된 것으로 간주 되려면 속성 이 선택 사항이어야 합니다.

그러나 A가 생성되면 instanceOfB를 사용하여 instanceOfB에 액세스해야 하는 것은 성가신 일입니다! B 있어야 한다는 것을 알기 때문에

이를 피하기 위해 instanceOfB는 암시적 unwrapped optional(instanceOfB!)로 선언되며 instanceOfB만 사용하여 액세스할 수 있습니다. (게다가 컴파일러가 액세스를 다르게 최적화할 수도 있다고 생각 합니다).

그 예가 이 책의 464면에서 466면에 나와 있습니다.

요약:

  • 사용하다 ? 값이 미래에 0이 될 수 있다면 이를 테스트합니다.
  • 사용하다 ! 미래에 실제로 nil이 되어서는 안 되지만 처음에는 nil이어야 합니다.

구문상의 설탕을 넘어서야합니다.

완전히 다른 두 가지 다형성 유형이 있습니다. 구문 설탕은 이러한 유형 중 하나 또는 다른 하나를 사용합니다.

당신 Foo?이 유형으로 쓸 때 당신 이 정말로 가지고 있는 Optional<Foo>반면, 당신이 쓸 때 당신 Foo!은 정말로 가지고 있습니다 ImplicitlyUnwrappedOptional<Foo>.

이들은 두 가지 다른 유형이며 또한 다릅니다 Foo.


사용하여 생성한 ?값은 언급한 대로 일반 선택적 값이므로 선택적 바인딩( if let unwrappedValue = myOptionalValue)을 통해 또는 느낌표 구문을 사용하여 액세스해야 합니다 myOptionalValue!.doSomething().

사용하여 생성한 값을 !암시적으로 래핑되지 않은 옵션이라고 합니다. 그것들을 사용하면 사용하기 전에 수동으로 포장을 풀 필요가 없습니다. 할 때 val myOptionalValue!.doSomething().

값은 myOptionalValue직접 사용할 때 자동으로 언래핑 되지만 실제로 값이 없을 때(있을 때) 암시적으로 언래핑된 값에 액세스하면 nil런타임 오류가 발생 하므로 주의하세요 .


? (선택 사항) 변수에 nil 값이 포함될 수 있음을 나타냅니다
. (unwrapper) 는 런타임에 변수가 사용될 때(값을 얻으려고 시도할 때) 변수에 메모리(또는 값)가 있어야 함을 나타냅니다.

주요 차이점은 옵셔널이 nil일 때 옵셔널 체이닝이 정상적으로 실패하는 반면, 옵셔널이 nil일 때 강제 언래핑은 런타임 오류를 트리거한다는 것입니다.

선택적 연결이 nil 값에 대해 호출될 수 있다는 사실을 반영하기 위해 선택적 연결 호출의 결과는 쿼리하는 속성, 메서드 또는 아래 첨자가 비선택적 값을 반환하더라도 항상 선택적 값입니다. 이 선택적 반환 값을 사용하여 선택적 연결 호출이 성공했는지(반환된 선택 사항에 값이 포함됨) 또는 체인의 nil 값으로 인해 성공하지 못한지(반환된 선택적 값은 nil임) 확인할 수 있습니다.

특히, 선택적 연결 호출의 결과는 예상되는 반환 값과 동일한 유형이지만 선택적으로 래핑됩니다. 일반적으로 Int를 반환하는 속성은 Int? 선택적 체인을 통해 액세스할 때.

var defaultNil : String?  // declared variable with default nil value
println(defaultNil) >> nil  

var canBeNil : String? = "test"
println(canBeNil) >> optional(test)

canBeNil = nil
println(canBeNil) >> nil

println(canBeNil!) >> // Here nil optional variable is being unwrapped using ! mark (symbol), that will show runtime error. Because a nil optional is being tried to get value using unwrapper

var canNotBeNil : String! = "test"
print(canNotBeNil) >> "test"


var cantBeNil : String = "test"
cantBeNil = nil // can't do this as it's not optional and show a compile time error

자세한 내용은 Apple Developer Commitee의 문서를 참조하십시오.


String!종류는라고 암시 적으로 풀어 선택 사항 :

때로는 프로그램 구조에서 해당 값이 처음 설정된 후에 옵셔널이 항상 값을 갖는다는 것이 분명합니다. 이러한 경우 항상 값을 가지고 있다고 안전하게 가정할 수 있기 때문에 액세스할 때마다 옵셔널의 값을 확인하고 래핑 해제할 필요를 제거하는 것이 유용합니다.

이러한 종류의 옵셔널은 암시적으로 언래핑된 옵셔널로 정의됩니다. 선택 항목으로 만들려는 유형 뒤에 물음표(String?) 대신 느낌표(String!)를 배치하여 암시적으로 래핑되지 않은 선택 항목을 작성합니다.


선택적 연결 섹션에서 답을 찾을 수 있습니다.

예시 클래스:

class Person {
    var residence: Residence?
}

class Residence {
    var numberOfRooms = 1
}

이 사람의 거주지의 numberOfRoom 속성에 액세스하려고 하면 거주 후 느낌표를 배치하여 해당 값의 래핑 해제를 강제 실행하면 래핑 해제할 거주 값이 없기 때문에 런타임 오류가 발생합니다.

let roomCount = john.residence!.numberOfRooms
// this triggers a runtime error

위의 코드는 john.residence가 nil이 아닌 값을 가질 때 성공하고 roomCount를 적절한 방 수를 포함하는 Int 값으로 설정합니다. 그러나 이 코드는 위에서 설명한 것처럼 거주가 nil일 때 항상 런타임 오류를 발생시킵니다.

선택적 연결은 numberOfRooms 값에 액세스하는 대체 방법을 제공합니다. 선택적 연결을 사용하려면 느낌표 대신 물음표를 사용하세요.

if let roomCount = john.residence?.numberOfRooms {
    println("John's residence has \(roomCount) room(s).")
} else {
    println("Unable to retrieve the number of rooms.")
}
// prints "Unable to retrieve the number of rooms."

위의 @tarmes가 잘 언급했습니다. 암시적 선택 사항의 또 다른 사용법을 확인했습니다.

내가 선택 사항이 있다고 가정 해 봅시다 Int.

let firstInt: Int? = 9

그리고 선택적 패턴 일치를 사용하려고 하고 Int이것을 다음과 같이 선택적으로 사용하려고 합니다 .

if case let myFirstInt? = firstInt where myFirstInt > 1 {
    print("Valid")
} else {
    print("Invalid")
}

optional 과 연결된 조건에 myFirstInt대해 안전 하도록 로컬 매개변수와 함께 암시적 optional을 사용 하고 있습니다 . 지금, 내가 as 하면 else 조건이 실행됩니다. 대신 force-unwrap을 사용 하면 다음과 같이 충돌이 발생할 수 있습니다.nilfirstIntfirstIntnilfirstInt

여기에 이미지 설명 입력

ReferenceURL : https://stackoverflow.com/questions/24083842/what-is-the-difference-between-string-and-string-two-ways-of-creating-an-opti

반응형

'IT이야기' 카테고리의 다른 글

언제 cudaDeviceSynchronize를 호출  (0) 2021.10.23
Git용 Jenkins 내에서 SSH 키 관리  (0) 2021.10.23
IdentityServer 흐름  (0) 2021.10.23
사용 시기: 튜플 대 클래스 c# 7.0  (0) 2021.10.23
C#용 린트  (0) 2021.10.22