( 스위프트 2.x )
또한 일반적인 형식 메서드에 대해 파란색 -rpint를 포함하는 프로토콜, 예를 들어 프로토콜과 같은 일부 형식 제약 조건을 따르는 모든 일반 배열 요소에 대한 사용자 지정 기능 유틸리티를 포함하는 프로토콜에 맞게 배열을 확장 할 수 있습니다 MyTypes
. 이 접근 방식을 사용하는 이점은 일반 배열 인수를 사용하여 함수를 작성할 수 있다는 것입니다. 이러한 배열 인수는 프로토콜과 같은 사용자 정의 함수 유틸리티 프로토콜을 준수해야한다는 제약이 있습니다 MyFunctionalUtils
.
배열 요소를로 제한하는 유형을 사용하여 암시 적 으로이 동작을 얻을 수 있습니다 MyTypes
. 또는 아래 설명 된 방법에서 볼 수 있듯이 일반 배열 함수 헤더에 입력 배열을 직접 표시합니다. 을 준수합니다 MyFunctionalUtils
.
MyTypes
타입 제약으로 사용 하기 위한 프로토콜 로 시작합니다 . 이 프로토콜을 사용하여 제네릭에 맞추려는 유형을 확장하십시오 (아래 예는 기본 유형 Int
및 Double
사용자 정의 유형을 확장 합니다 MyCustomType
)
/* Used as type constraint for Generator.Element */
protocol MyTypes {
var intValue: Int { get }
init(_ value: Int)
func *(lhs: Self, rhs: Self) -> Self
func +=(inout lhs: Self, rhs: Self)
}
extension Int : MyTypes { var intValue: Int { return self } }
extension Double : MyTypes { var intValue: Int { return Int(self) } }
// ...
/* Custom type conforming to MyTypes type constraint */
struct MyCustomType : MyTypes {
var myInt : Int? = 0
var intValue: Int {
return myInt ?? 0
}
init(_ value: Int) {
myInt = value
}
}
func *(lhs: MyCustomType, rhs: MyCustomType) -> MyCustomType {
return MyCustomType(lhs.intValue * rhs.intValue)
}
func +=(inout lhs: MyCustomType, rhs: MyCustomType) {
lhs.myInt = (lhs.myInt ?? 0) + (rhs.myInt ?? 0)
}
프로토콜 MyFunctionalUtils
(추가적인 일반적인 배열 함수 유틸리티의 청사진을 잡고 있음)과 그 후 Array by MyFunctionalUtils
; 블루 프린트 방식의 구현 :
/* Protocol holding our function utilities, to be used as extension
o Array: blueprints for utility methods where Generator.Element
is constrained to MyTypes */
protocol MyFunctionalUtils {
func foo<T: MyTypes>(a: [T]) -> Int?
// ...
}
/* Extend array by protocol MyFunctionalUtils and implement blue-prints
therein for conformance */
extension Array : MyFunctionalUtils {
func foo<T: MyTypes>(a: [T]) -> Int? {
/* [T] is Self? proceed, otherwise return nil */
if let b = self.first {
if b is T && self.count == a.count {
var myMultSum: T = T(0)
for (i, sElem) in self.enumerate() {
myMultSum += (sElem as! T) * a[i]
}
return myMultSum.intValue
}
}
return nil
}
}
마지막으로, 다음과 같은 경우에 각각 일반 배열을 취하는 함수를 보여주는 테스트와 두 가지 예
배열 매개 변수를 'MyTypes'(함수 )로 제한하는 유형을 통해 배열 매개 변수가 'MyFunctionalUtils'프로토콜을 준수한다는 암시 적 주장을 표시 bar1
합니다.
배열 매개 변수가 'MyFunctionalUtils'프로토콜 (function )을 준수 함을 명시 적으로 표시 bar2
합니다.
테스트 및 예제는 다음과 같습니다.
/* Tests & examples */
let arr1d : [Double] = [1.0, 2.0, 3.0]
let arr2d : [Double] = [-3.0, -2.0, 1.0]
let arr1my : [MyCustomType] = [MyCustomType(1), MyCustomType(2), MyCustomType(3)]
let arr2my : [MyCustomType] = [MyCustomType(-3), MyCustomType(-2), MyCustomType(1)]
/* constrain array elements to MyTypes, hence _implicitly_ constraining
array parameters to protocol MyFunctionalUtils. However, this
conformance is not apparent just by looking at the function signature... */
func bar1<U: MyTypes> (arr1: [U], _ arr2: [U]) -> Int? {
return arr1.foo(arr2)
}
let myInt1d = bar1(arr1d, arr2d) // -4, OK
let myInt1my = bar1(arr1my, arr2my) // -4, OK
/* constrain the array itself to protocol MyFunctionalUtils; here, we
see directly in the function signature that conformance to
MyFunctionalUtils is given for valid array parameters */
func bar2<T: MyTypes, U: protocol<MyFunctionalUtils, _ArrayType> where U.Generator.Element == T> (arr1: U, _ arr2: U) -> Int? {
// OK, type U behaves as array type with elements T (=MyTypes)
var a = arr1
var b = arr2
a.append(T(2)) // add 2*7 to multsum
b.append(T(7))
return a.foo(Array(b))
/* Ok! */
}
let myInt2d = bar2(arr1d, arr2d) // 10, OK
let myInt2my = bar2(arr1my, arr2my) // 10, OK
extension T[]
XCode에서 배열 유형을 Command- 클릭 할 때 동일한 비트가 표시되지만 오류없이이를 구현하는 방법은 보이지 않습니다.