2014-12-19 4 views
2

여기 내 코드입니다 :신속한 일반 기능 오류?

func swapTwoValues<T>(inout a: T, inout b: T){ 
    let temp = a 
    a = b 
    b = temp 
} 
var aInt = 5 
var bInt = 98 
swapTwoValues(&aInt, &bInt) 

때 호출 기능 swapTwoValues ​​(), "T"는 INT 타입

입니다하지만

func swapTwoValues<T,S:String>(inout a: T, inout b: T , inout c: S){ 
    let temp = a 
    a = b 
    b = temp 
    c = "Hi" 
} 
var aInt = 5 
var bInt = 98 
var cStr = "Hello" 
swapTwoValues(&aInt, &bInt,&cStr) 

이 오류가 표시됩니다에이 코드를 변경할 때, 하지만 왜? 내가 문자열 유형에 "S"로 설정

, 그것은 문자열 구조체이며, 구조체가 확장 될 수 없다는 단순한 이유 작동하지해야 올바른

답변

0

코드 <S: String>을 것입니다. 따라서 S는 실제로 유효하지 않은 유형입니다.

c을 열거 형으로 사용하려는 경우 <S: RawRepresentable where S.RawType == String>을 사용해야합니다.

String 유형에 기능을 추가하려는 경우 c이 일반 문자열이어야하고 String의 확장을 사용하여 기능을 구현해야합니다.

String을 실제로 객체로 확장하려면 NSString을 확장해야합니다. 예를 들어

:

class MyString: NSString { 
    // My code 
} 

다음은 일반적인된다 당신 : <S: NSString>를 완전히 유효한.

확장 NSString의 단점은 유형이 이제는 참조 유형이지만 Swift의 일부일 뿐이므로 구조체를 상속 할 수는 없습니다.

+0

구조체를 확장 할 수없는 이유는 무엇입니까? 자습서 "확장 기능은 기존 클래스, 구조 또는 열거 유형에 새로운 기능을 추가합니다." –

+0

죄송합니다. 단어를 잘못 사용했습니다. 구조는 "확장"을 사용하여 확장 할 수 있습니다. 그러나 그들은 상속으로 "확장"될 수 없습니다. "확장"에 특별한 제한이 있습니다 (예 : 새 멤버 변수를 저장할 수 없어 형식의 크기가 커짐) – Zenton

1

A: B 구문을 사용하면 일반 자리 표시자가 프로토콜을 준수하거나 기본 클래스에서 상속되는 형식을 나타내야하기 때문에 작동하지 않는 이유가 있습니다. String은 프로토콜 또는 클래스가 아닌 구조체이므로 오류 ("비 프로토콜, 클래스가 아닌 유형 'String'으로부터의 상속)을 얻습니다. Optional과 같은 열거 형을 사용하면 동일하게됩니다.

이유가 무엇입니까? 두 가지 유형의 코드를 작성한 다음 Swift에서 컴파일 할 때 해당 기능을 해당 요구 사항을 충족하는 여러 유형에 적용 할 수 있습니다. Structs는 상속을 허용하지 않습니다 (클래스 만 할 수 있습니다). func f<S: String>(c: S)이라고 말하면 일반 placeholder S을 정의 할 수 있습니다. 그 유형은 String이고 다른 유형은 없습니다. 어떤 다른 가능한 유형이 없기 때문에 String을 비 일반 매개 변수, 즉 func f(s: String)으로 지정합니다. 반면에

클래스 상속을 허용 할, 그래서 당신은 당신이 때문에 컴파일시 func f:<S: MyClass>(c: S)를 작성할 수 MyClass 클래스가 있다면, 어쩌면 당신은, MyInheritedClassMyClass에서 상속하는 클래스를 전달할 수 있습니다.

구조체는 프로토콜을 준수 할 수 있습니다.그래서 예를 들어,이 경우에만 하나가 다른 것보다 더 컸다 값을 교환 뭔가를 쓰고 싶다 가정 : swapIfGreater가 호출

컴파일시에
func swapIfGreater<T: Comparable>(inout a: T, inout b: T) { 
    // this is allowed because conformance to the the 
    // Comparable protocol guarantees > is available 
    if a > b { 
     // avoid temporaries with this one weird trick :) 
     (a, b) = (b, a) 
    } 
} 

// i and j are Ints (a kind of struct) 
var i = 40, j = 30 
swapIfGreater(&i, &j) 

// s1 and s2 are Strings 
var s1 = "zebra", s2 = "aardvark" 
swapIfGreater(&s1, &s2) 

// Bool doesn’t support the Comparable protocol 
// (false is not “less than” or “greater than” true) 
// so this won’t compile: 
var b1 = true, b2 = false 
swapIfGreater(&b1, &b2) 

는 스위프트의 슬롯에 사용되는 유형에 보이는 일반 자리 표시 자 T (여기에 Int 또는 String)을 입력하고 요구 사항을 충족하는지 확인합니다 (프로토콜 Comparable을 준수해야 함). 그렇다면 전달하는 유효한 유형별로 함수 버전을 작성하는 것으로 간주 할 수 있습니다.

// It’s as if Swift writes two versions of swapIfGreater for you automatically: 
func swapIfGreater(inout a: Int, inout b: Int) { 
    if a > b { 
     (a, b) = (b, a) 
    } 
} 

func swapIfGreater(inout a: String, inout b: String) { 
    if a > b { 
     (a, b) = (b, a) 
    } 
} 
+0

Foundation을 가져 오면 String이 암시 적으로 NSString으로 변환됩니다. NSString은 클래스이므로 S : String이이 경우 오류를 발생시키는 지 궁금합니다. – mustafa