2009-09-29 9 views
16

名前付きタプルを許可する言語があるかどうか疑問に思っていました。つまり、異なるタイプの複数の変数と設定可能な名前を持つオブジェクトです。名前付きタプルを許可する言語

例えば:

public NamedTuple<double:Speed, int:Distance> CalculateStuff(int arg1, int arg2) 

var result = CalculateStuffTuple(1,2); 

Console.WriteLine("Speed is: " + result.Speed.ToString()) 
Console.WriteLine("Distance is: " + result.Distance.ToString()) 

私は、動的には、このような機能をサポートしている可能性がどのように想像することができます。私が通常泳ぐ静的言語(C#のような)は辞書を行うことができますが、すべての項目が同じ型でない限り型の安全ではありません。または、タプルタイプを使用することもできますが、メンバーの名前(Var1、Var2など)が固定されていることを意味します。

小さなカスタムクラスを書くこともできますが、これは避けたい状況です。

静的な言語でマクロ処理言語があなたのためにスクリプトを作成できるとは思いますが、そのような言語はわかりません。

これは私の答えのthis question about return typesから出てきます。

+0

私はカスタムクラス/構造体を避けるしたい理由は、私はタイピングが好きではないということです!それ以上のことはありません。 – ligos

+0

この行にはタプルは含まれません。 var result = CalculateStuffTuple(1,2); –

答えて

18

C#では、匿名の型があります。これらは似ていますが、自分の限界を持っている:あなたは(脆い)「の例でキャスト」、反射、またはdynamicを使用しない限り

var result = new { Speed = 12.4, Distance = 8, Caption = "car 1" }; 

しかし、呼び出し側としてこれらを消費するのは難しいです。 3人のうち、最後は最もおいしいです。

dynamic result = GetSomething(); 
Console.WriteLine(result.Speed); 
Console.WriteLine(result.Distance); 

ほとんどの場合、通常のクラスを使用することをお勧めしますが、このアプローチには実用的な用途があります。たとえば、ASPでどのように使用されているかを見てください。NET MVCを使用して、構成情報を簡単に(便利には辞書を必要とするように)渡すことができます。 jQueryのようにオブジェクトのプロパティとしてオプションを渡すことができるようなビットです。

+0

これは私が求めていたものに最も近いようです(少なくともC#で)。 – ligos

-1

タプルは、さまざまなタイプのデータを保持する構造体です。名前付きプロパティが本当に必要な場合は、カスタムタイプを作成するか、匿名型をその場で作成する必要があります。

私はこれをサポートする静的な型指定言語について認識していませんが、C#はそうではありません。

3

Pythonのcollections.namedtupleのようなものですか?まあ、Python(現在のバージョン2.6と3.1)はそれらをサポートしています;-)。しかし、真剣に、私は静的に型付けされた言語を組み込みとして持つことは知らない。

2

C#で構造体やクラスを使用すると何が問題になりますか?

public class SpeedDistance{ 
    public double Speed; 
    public int Distance; 
} 
+2

まあ、パブリックフィールドはもちろん、悪い考えです...しかし、 'public double Speed {get; set;}'はやります;-p –

+1

私はタプルが不変であるのが好きです。そしてそれにはreadonly変数とコンストラクタが必要です。コンストラクタはちょうど時間がかかり始めます。 – ligos

+1

すべてのクラスが含まれている場合に限り、パブリックフィールドは正常です。しかし、タプルは、他のライブラリに渡すときに役立つ素晴らしいプロパティをたくさん持つこともできます。それらが毎回書かれている場合、それらは相互運用しません。 –

3

これは、あなたが探している正確に何であるならば、私はわからないんだけど、Haskellで、あなたが指定した名前と型を持つレコードを持つことができます。

data Movement = Movement { speed :: Double, distance :: Int } deriving (Show) 

main = do 
    print $ Movement 3.14 100 
    print Movement {distance = 5, speed = 2.1} 
    print Movement {speed = 9, distance = -4} 

は出力:

 
Movement {speed = 3.14, distance = 100} 
Movement {speed = 2.1, distance = 5} 
Movement {speed = 9.0, distance = -4} 

しかし、技術的にはタプルではありません。 Haskell にはタプルがありますが、私が知る限り名前は付けられていません。

これは実際にC派生言語の単純な構造体から遠く離れているわけでもありません。たぶん私は質問に何かを忘れた。

6

Eiffelでは、名前付きタプルを使用できます。

5

私は知っています。

  • パイソン(ダイナミック、強い型付け)
  • エッフェル(静的、文字列タイピング)の両方がLispの.NET

    で、おそらく使用することができます

、あなたは、Lispで何かを行うことができます。

39

古い質問ですが、もっと良い解決策が必要だと思います。

タプル型を利用して、名前付きパラメータを取得できますが、.Item1、.Item2などを意味のあるプロパティ名でラップするカスタム名前付き型にラップします。

タプルにはコードを読めないようにする名前のないパラメータがありますが、IComparable、IStructuralEquatableなどを実装して保存する時間を無視することはできないため、安全に構造体を辞書として使用できるようになりますたとえば、キーです。

私は、これは非常に楽しい妥協だと思う:代わりにこのゴミの

public class Velocity : Tuple<double, double, string> 
{ 
    public Velocity(double Speed, double Direction, string Units) : base(Speed, Direction, Units) { } 
    public double Speed { get { return this.Item1; } } 
    public double Direction { get { return this.Item2; } } 
    public string Units { get { return this.Item3; } } 
} 

Tuple<double, double, string> myVelocity = new Tuple<double, double, string>(10, 2.34, "cm/s"); 
System.Diagnostics.Debug.Print("Speed: " + myVelocity.Item1); 
System.Diagnostics.Debug.Print("Direction: " + myVelocity.Item2); 
System.Diagnostics.Debug.Print("Units: " + myVelocity.Item3); 

あなたがこれを行うために取得:

Velocity myVelocity2 = new Velocity(10, 2.34, "cm/s"); 
System.Diagnostics.Debug.Print("Speed: " + myVelocity2.Speed); 
System.Diagnostics.Debug.Print("Direction: " + myVelocity2.Direction); 
System.Diagnostics.Debug.Print("Units: " + myVelocity2.Units); 

をそして、あなたはまだ利益あなたが辞書などの複雑なキーとしてそれを使用させるすべての素晴らしいタプルの機能から。

唯一の欠点は、1つのメソッドのスコープ内でこのタプルを使用することを計画している場合は、そのメソッドを含むクラスのスコープ内で型を宣言する必要があることです。ほとんどのアプリケーションで、私はそれが問題だとは思わない。

+0

それは実際にあまりにも悪くないです。私は、 'Tuple <>'の周りに小さなクラスの束をラップする必要があることを除いて。しかし、IEquatable、IComparableなどを再実装する必要があるよりも優れています。 – ligos

+1

私はこれを考えなかったとは思えません。スーパー便利です。 –

+0

私が探していたソリューションです。すばらしいです :) –

2

このような言語がいくつか存在します。そのような名前付きタプルの単語は「レコード」です。 ML言語ファミリは、対応するタイプとともにそのようなレコードを有する。具体的な言語には、SML、OCaml、そして重要なF#があります。このリンクは、F#のレコードについて説明しますhttp://en.wikibooks.org/wiki/F_Sharp_Programming/Tuples_and_Records#Defining_Records

0

はあなたAlainありがとうございました。あなたのヒントを使いました。

カルーセル

<div id="owl" class="owl-carousel owl-theme"> 
    @foreach (var image in Model.Sketches) 
    { 
     <div class="item" > 
      <a href="@image.SketchHref" id="[email protected]" target="_blank" > 
       <img id="[email protected]" class="lazyOwl" style="border:1px solid #d1c7c7;outline : 0;max-height:350px;max-width:400px;" 
        title="click for full size" alt="@image.SketchName" data-src="@image.SketchHref" /></a> 
        <div style="text-align:left;height:auto;vertical-align:bottom;padding:2px;font-size:1em;color:#DF3A01;">Sketch @image.SketchNumber of @Model.Sketches.Count()</div> 
     </div> 
    } 
    </div> 

の動的画像ローダーとC#

public List<Sketches> Sketches 
    { 
     get 
     { 
      List<Sketches> hrefs = new List<Sketches>(); 

のために/ * イメージ名はフォルダの場所 例一致します1234101005_001を。GIFが等しくなる "C:1005_BLD \ \ 10 \ 1234 \ \画像を" */

  var sketchFolder = Regex.Replace(some_image, @"(\d{4})(\d{2})(\d{4})", @"c:\Sketches\$1\$2\$3\_BLD"); 
      var sketchHref = Regex.Replace(some_image, @"(\d{4})(\d{2})(\d{4})", @"/sketches/$1/$2/$3/_BLD"); 
      Int16 i = 0; 

      if (System.IO.Directory.Exists(sketchFolder)) 
      { 
       List<string> gifs = GetGifs(sketchFolder); 

       gifs.ForEach(delegate(String gif) 
       { 
        string s = sketchHref + "/" + gif; 
        string f = sketchFolder + "/" + gif; 

        if (System.IO.File.Exists(f)) 
        { 
         Sketches sketch = new Sketches(s, (++i).ToString(), gif); 
         hrefs.Add(sketch); 
        } 
        else // gif does not exist 
        { 
         Sketches sketch = new Sketches("placeholder.png", (++i).ToString(), gif); 
         hrefs.Add(sketch); 
        } 
       }); 
      } 
      else // folder does not exist 
      { 
       Sketches sketch = new Sketches("placeholder.png", (++i).ToString(), ""); 
       hrefs.Add(sketch); 
      } 
      return hrefs; 
     } 
    } 

public class Sketches : Tuple<string, string, string> 
{ 
    public Sketches(string SketchHref, string SketchNumber, string SketchName) : base(SketchHref, SketchNumber, SketchName) { } 
    public string SketchHref { get { return this.Item1; } } 
    public string SketchNumber { get { return this.Item2; } } 
    public string SketchName { get { return this.Item3; } } 
} 
1

スウィフトは、名前のタプルを可能にします。

let interval = (start: 0, end: 10) 
let start = interval.start 

これらは実際には匿名の構造です。

関連する問題