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など)。

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

マクロ処理言語が静的言語でそのようなスクリプトを作成できると想像できましたが、そのような言語については知りません。

これは、リターンタイプに関するこの質問からの私の答えから出てきます。

4

12 に答える 12

40

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

タプル型を利用して名前付きパラメーターを取得できますが、.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);

また、辞書などで複雑なキーとして使用できるすばらしいタプル機能をすべて利用できます。

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

于 2012-08-08T16:37:30.633 に答える
18

C#では、匿名タイプがあります。これらは似ていますが、独自の制限があります。

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

ただし、 「例によるキャスト」(脆弱)、リフレクション、またはを使用しない限り、これらを発信者として使用することは困難dynamicです。3つのうち、最後が最も食欲をそそります。

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

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

于 2009-09-29T04:29:23.207 に答える
6

Eiffelは名前付きタプルを許可します。

于 2009-09-30T16:46:10.770 に答える
6

これは、C#7以降でサポートされるようになりました

(double speed, int distance) CalculateStuff(int arg1, int arg2)

var result = CalculateStuff(1,2);

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

参照:https ://blogs.msdn.microsoft.com/dotnet/2017/03/09/new-features-in-c-7-0/

于 2016-04-14T21:34:21.730 に答える
5

私は知っています。

  • Python(動的、強い型付け)
  • エッフェル(静的、文字列型付け)

どちらも.netで使用できます

そしておそらくLisp、あなたはLispで何でもすることができます。

于 2012-02-03T11:55:15.567 に答える
3

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

于 2009-09-29T03:21:29.897 に答える
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}

出力:

動き{速度=3.14、距離= 100}
動き{速度=2.1、距離= 5}
動き{速度=9.0、距離= -4}

しかし、技術的にはタプルではありません。Haskellにはタプルがありますが、私が知る限り、名前を付けることはできません。

これは、Cから派生した言語の単純な構造体からもそう遠くはありません。多分私は質問の何かを逃しました。

于 2009-09-29T03:34:26.687 に答える
2

C#で構造体またはクラスを使用することの何が問題になっていますか?

public class SpeedDistance{
  public double Speed;
  public int Distance;
}
于 2009-09-29T03:23:04.270 に答える
2

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

于 2013-01-23T10:45:25.593 に答える
1

Swiftでは名前付きタプルを使用できます。次のように書くことができます:

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

それらは事実上匿名の構造です。

于 2015-08-04T07:48:03.833 に答える
0

ありがとうアラン。これが私があなたのチップをどのように使ったかです。

カルーセル用のダイナミックイメージローダー

<div id="owl" class="owl-carousel owl-theme">
    @foreach (var image in Model.Sketches)
    {
        <div class="item" >
            <a href="@image.SketchHref" id="a_@image.SketchNumber" target="_blank" >
                <img id="sketch_@image.SketchNumber" 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:\ images \ 1234 \ 10 \1005_BLD\"に等しくなります*/

            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; } }
}
于 2015-06-24T14:39:27.400 に答える
-1

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

これをサポートする静的に型付けされた言語も私は知りませんが、C#は確かにサポートしていません。

于 2009-09-29T03:21:00.287 に答える