2016-02-02 2 views
10

たとえば、Swiftのタプルは、関数が複数の値を返す簡単な方法として機能することを理解しています。しかし、この「シンプルさの側面」を超えて、構造体の代わりにタプルを使用する必要性はあまりありません。Swiftのタプルとストラクチャ

私の質問:設計上、タプルが明らかに構造体よりも優れた選択肢となるシナリオはありますか?

+2

タプルは、ローカルでのみ使用されるデータ構造にのみ有用であると私は思います。それ以外の場合は、すべてのデータ構造を「匿名のタプルとして浮動」させるのではなく、適切に定義し、構造体またはクラスとして「ラベル付け」することをお勧めします。しかし、私は間違っているとは思っていません... – George

+1

私はシンプルさの面はそれがすべてのものだと思う:)構造体を定義する必要はなく、コードは少なくて済みます。 Swiftには、シンプルさの目的に役立つ多くの機能があります。 –

答えて

6

少し「議論」自然のこの質問が、私は時々タプルを構造よりも好むことに賛成して2つの点を追加します。


スウィフト2.2では限られたサイズのタプル

ため

ネイティブEquatableの適合性、サイズ6までのタプルは、それはメンバーが

これはタプルが自然な選択であることを意味します限られた範囲でより小さな構造を使用すること。

など。 (1)を使用して、次の例を考えてみます。構造

struct Foo { 
    var a : Int = 1 
    var b : Double = 2.0 
    var c : String = "3" 
} 

var a = Foo() 
var b = Foo() 

// a == b // error, Foo not Equatable 

/* we can naturally fix this by conforming Foo to Equatable, 
    but this needs a custom fix and is not as versatile as just 
    using a tuple instead. For some situations, the latter will 
    suffice, and is to prefer.         */ 
func == (lhs: Foo, rhs: Foo) -> Bool { 
    return lhs.a == rhs.a && lhs.b == rhs.b && lhs.c == rhs.c 
} 

(2):タプル異なるタイプのタプルに

/* This will be native in Swift 2.2 */ 
@warn_unused_result 
public func == <A: Equatable, B: Equatable, C: Equatable>(lhs: (A,B,C), rhs: (A,B,C)) -> Bool { 
    return lhs.0 == rhs.0 && lhs.1 == rhs.1 && lhs.2 == rhs.2 
} 
/* end of native part ...   */ 

var aa = (1, 2.0, "3") 
var bb = (1, 2.0, "3") 

aa == bb // true 
aa.0 = 2 
aa == bb // false 

ジェネリックアクセス:異なるタイプの構造のためよりも汎用性

上記(==の機能を比較する)からは、タプルは、.0.1 ...サフィックスを使用して匿名のメンバープロパティにアクセスすることができるので、ジェネリックスのコンテキストで簡単に処理できます。構造体の場合、この動作を模倣する最も簡単な方法は、実行時イントロスペクションなどのツールを必要とする非常に複雑になります。e.g. thisを参照してください。

+0

それは面白いです。 – George

+0

関数のパラメータと戻り値のタプルは、関数が何をするのかを本当に明確にすることができます。 'func multiply(aNumber number:Int、anotherNumberによって:Int) - > Int'。 'struct'として、これは全く明確ではありません。 'func乗算(twoNumbers:TwoNumbersStruct) - > Int' –

0

これをjava-objective-Cとみなします。 あなたはあなたのプロジェクトでこのタイプのデータソースにプラグインする必要があります(あなたがアンドロイドに巨大なベースコードを持っていて、すべてを最初からやりたくないので、java型のデータソース(例えばhashmapのような)基本的には、目的関数型から型定義されています。 これは、あなたが持っているものによっては簡単にはプラグインできません。コレクションビューのために素敵な配列が必要な場合は、javaデータソースでいっぱいになるタプルの配列がうまくいくでしょう。 これを説明するためのコードの小さなサンプル:

var myJavaVar = JavaUtilLinkedHashMap() 
var headerArray : [(varName : String, param : Int, varId : jlong)] = [] 


myJavaVar = myStaticMethodToGetMyVar 

    // get var array 
    let keySetJava = myJavaVar.keySet().toArray() 
    for jCounter in 0..<Int(myJavaVar.size()){ 
     // id for index 
     let key : Int = keySetJava.objectAtIndex(UInt(jCounter)) as! Int 
     let varId = jlong.init(key) 
     let varName = myMethodToGetName(varId) 
     let myParam : Int = myJavaVar.getWithId(keySetJava.objectAtIndex(UInt(jCounter))) as! Int 
     // append data to the array 
     headerArray.append((varName: categoryName, param : myParam,duration: duration, varId: varId)) 
    } 

あなたは、その後(ごcollectionview方法で)このようなあなたのデータを取得することができます:

let time = headerArray[indexPath.section].param 
+0

しかし、タプルを使用する代わりに、構造体を定義して配列内で使用することを妨げるのはなぜですか?なぜタプルは構造体より優れていますか?タプルはコードを読みにくくするだけです(これは主観的ですが、私は知っています)。 – George

+0

タプルを使用することはすでにお尻の痛みでした、あなたはこれのための構造体を使用したいですか? これはヘッダーセルのためだけのものです。通常のセル配列を塗りつぶす必要があるときは、どのようなものか想像してみましょう。 名前付きパラメータを使用すると、コードを読みにくくすることができますか? –

+0

メンバーvarName、param、およびvarIdを持つHeaderDataという名前の構造体(たとえば)を定義することができます。あなたが持っている: のvar headerArray:[HeaderData] = [] – George

関連する問題