允许命名元组的语言

lig*_*gos 16 c# tuples return-value

我想知道是否有任何语言允许命名元组.即:具有不同类型和可配置名称的多个变量的对象.

例如:

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())
Run Code Online (Sandbox Code Playgroud)

我可以设想动态如何支持这样的功能.我经常游泳的静态语言(如c#)可以做一个字典,但除非所有项目属于同一类型,否则这不是类型安全的.或者你可以使用元组类型,但这意味着你有成员的固定名称(Var1,Var2等).

你也可以写一个小的自定义类,但这是我想避免的情况.

我可以想象一个宏处理语言可以用静态语言为你编写类似的东西,但我不知道这样的语言.

这来自我关于回归类型的问题的答案.

Ala*_*ain 40

老问题,但我认为需要更好的解决方案.

您可以通过利用Tuple类型获取命名参数,但将其包装在自定义命名类型中,该类型将.Item1,.Item2等包装在有意义的属性名称中.

我也讨厌Tuples有未命名的参数使代码不可读的事实,但是不能忽略它自己实现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; } }
}
Run Code Online (Sandbox Code Playgroud)

而不是这个垃圾:

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);
Run Code Online (Sandbox Code Playgroud)

你可以这样做:

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);
Run Code Online (Sandbox Code Playgroud)

您仍然可以从所有精彩的元组功能中受益,这些功能可以让您将其用作词典中的复杂键等.

唯一的缺点是,如果您只计划在单个方法的范围内使用此元组,则必须在该方法的包含类的范围内声明一个类型.对于大多数应用程序,我认为这不是问题.


Mar*_*ell 18

在C#中,您有匿名类型; 这些是相似的,但有其自身的局限性:

var result = new { Speed = 12.4, Distance = 8, Caption = "car 1" };
Run Code Online (Sandbox Code Playgroud)

但是,除非你使用"按示例执行"(脆弱),反射或,否则很难将它们作为调用者使用dynamic.在这三个中,最后一个是最开胃的.

dynamic result = GetSomething();
Console.WriteLine(result.Speed);
Console.WriteLine(result.Distance);
Run Code Online (Sandbox Code Playgroud)

在大多数情况下,使用常规课程会更好一点 - 但这种方法确实有一些实际用途; 例如,看看它们在ASP.NET MVC中如何使用它来简单方便地传递配置信息(否则需要字典).有点像jQuery如何允许您将选项作为对象的属性传递.


小智 6

Eiffel允许命名元组.


Ben*_*ttr 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())
Run Code Online (Sandbox Code Playgroud)

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


ctr*_*lor 5

我知道;

  • Python(动态,强类型)
  • Eiffel(静态,字符串输入)

两者都可以在.net中使用

也许Lisp,你可以用Lisp做任何事情.