2016-05-11 5 views
0

更新:これはPOPを学習するためのものです。私たちは< +>演算子を使用することができます知っているが、私は2つの要素を追加するために迅速な汎用的な関数を作成しようとしています一般的な追加機能を作成するためにswiftでPOPを使用する(

逃していますかを知りたい: - 数字などの要素は、単にそれらを追加した場合。 - 要素が文字列の場合は、連結します。ここで

は私のコードです:

protocol NumericType { 
    func +(lhs: Self, rhs: Self) -> Self 
} 

extension Double : NumericType {} 
extension Float : NumericType {} 
extension Int : NumericType {} 

protocol Addable { 
    func addGenerically<T>(element1: T, element2: T) -> T 
} 

extension Addable where Self:NumericType { 
    func addGenerically<T:NumericType>(element1: T, element2: T) -> T { 
     return (element1) + (element2) 
    } 
} 
// This throws error: inheritance from non protocol, non class type strings 
extension Addable where Self:String { 
    func addGenerically<T:String>(element1: T, element2: T) -> T { 
     return (element1) + (element2) 
    } 
} 


class MyVC: UIViewController{ 

override func viewDidLoad() { 
    super.viewDidLoad() 

    let n1 = Double(3.4) 
    let n2 = Double(3.3) 
    let n3 = Addable.addGenerically(n1, element2: n2) 
} 

任意のアイデアは、これを完了し、これを使用する方法?

+0

私はあなたがここで達成しようとしていることを本当に確信していません。 Swiftはあなたが使用する型に基づいてどの '+'演算子の実装を呼び出すかをすでに推測できます。文字列を連結して数字を追加するので、独自の 'addGenerically'関数を作成する必要はありません。 'Addable 'のように関数を実装することもできません。addGenerically(n1、element2:n2) ' - 単に' Addable'は具体的な型ではないので意味がないので、静的関数を呼び出すことはできません。 – Hamish

+0

@ originaluser2:これはPOPを学習するためのものです。私は何が欠けているのか知りたい –

答えて

1

ここでの問題は、エラーであると言われています。非プロトコル型でも非クラス型でも継承することはできません。

StringはSwiftのstructとして実装されており、構造体には継承がありません。 Stringの 'サブ構造体'を作成することはできません。この代わりに、共通の機能を定義し、階層感覚を提供するためにプロトコルが使用されます。

したがって、NumberTypeプロトコルの場合と同じように、拡張を制限するためにプロトコルを使用する必要があります。たとえば:

protocol AddableString { 
    func +(lhs: Self, rhs: Self) -> Self 
} 

extension String : AddableString {} 

extension Addable where Self:AddableString { 
    func addGenerically<T:AddableString>(element1: T, element2: T) -> T { 
     return (element1) + (element2) 
    } 
} 

はしかし、これはかなり長いったらしいある、と私はあなたが、とにかくこの機能を実装しようとしているかさえわからない - あなたは、既存の値にそれを使用する必要があるだろうとして、加算にその値を使用しません。あなたは、単にこのようにそれを使用することはできません。

Addable.addGenerically(n1, element2: n2) 

Addableが、具体的なタイプではないので、あなたはそれに静的関数を呼び出すことはできません。

プロトコルを1つのAddableプロトコルにマージすることで、コードを大幅に簡素化することをお勧めします。これにより、追加可能なタイプを定義することができます。したがって、addGenerically関数で使用できるタイプを定義することができます。たとえば、次のように

protocol Addable { 
    func +(lhs: Self, rhs: Self) -> Self 
} 

extension Double : Addable {} 
extension Float : Addable {} 
extension Int : Addable {} 
extension String : Addable {} 

func addGenerically<T:Addable>(lhs:T, rhs:T) -> T { 
    return lhs + rhs 
} 

... 

let n1 = 3.4 
let n2 = 3.3 

let n3 = addGenerically(n1, rhs: n2) 

私は新しいグローバル関数とグローバルな名前空間を汚染しないことを好む一般的であろうが - あなたはあなたが使用できるように、機能ではなくAddableの延長に単一Selfの引数を取ることを検討すべきです別のAddable上のメソッドを呼び出すことで、与えられたAddableを追加します(これはあなたのデモのために望まないかもしれないジェネリックを、削除が):

protocol Addable { 
    func +(lhs: Self, rhs: Self) -> Self 
    func addGenericallyWith(rhs: Self) -> Self 
} 

extension Double : Addable {} 
extension Float : Addable {} 
extension Int : Addable {} 
extension String : Addable {} 

extension Addable { 
    func addGenericallyWith(rhs:Self) -> Self { 
     return self + rhs 
    } 
} 

... 

let n1 = 3.4 
let n2 = 3.3 

let n3 = n1.addGenericallyWith(n2) 

すべての私たちがここで達成したことをノートに+を再実装されているがオペラトール! Swiftはあなたが使用しているタイプに基づいてどの+演算子の実装を呼び出すのかをすでに推測できるので、独自のaddGenerically関数を作成する必要はありません。

関連する問題