Java 的方法不支持多返回值,或者我们想达到返回多个值的效果时,不得不借用数组、列表或对象等来容纳多个值返回给调用者。这样使用起来不怎么优美,特别是为返回多个值而创造一个类成本有点高,如果 Java 也存在像 C# 那样的匿名类倒好。C# 如何使用匿名类返回多个值可参看本文后面的例子。
把 Scala 当作是一种脚本语言,它的灵活性就应该与 Perl 或 Ruby 看齐。Scala 的方法也可以有多个返回值,它实现些种行为,可借助于元组和列表类型,虽然你也可以发掘更多的实现方式,但到目前为止,我还是觉得用元组和列表最简单。
下面给出代码例子,让我们瞧瞧 Scala 如何实现方法多个返回值,并且作为对比我还会贴上 Perl, Ruby 和 C# 可以怎么实现多返回值。我是 Java 的惯用者,不过我一直都未否认,从语言层面 C# 比 Java 要显得优雅的多。
用元组实现 Scala 方法多返回值:
1 2 3 4 5 6 7 |
def foo = (100, "Unmi") //定义方法返回元组 val (num, name) = foo //用元组模式去接收方法 foo 的结果 println(num + ":" + name) //输出为 100:Unmi val values = foo //调用方法的结果直接给元组变量 println(values._1 + ":"+ values._2) //输出同样是 100:Unmi |
方法返回一个元组,里面可以组合任何多个的不同类型的返回值,调用时可以用元组变量或元组模式去接收方法的返回值,用元组模式的方式更好看些,也才能算作真正的多返回值。
用 List 实现 Scala 方法多返回值
1 2 3 |
def bar = List(100, "Unmi", "http://unmi.cc") //定义方法返回列表 val List(id, name, url) = bar println("id: " + id + ", name: " + name + ", url: " + url) |
上面用的是列表模式来接收返回列表的方法,这样达到对返回的列表元素的拆解。如果直接用列表变量来接收返回值,那么这与 Java 中用返回多个值组成的数组就没有一点区别了。
接下来我们来观摩一下 Perl, Ruby 和 C# 是怎么做到返回多个值的
Perl 的子过程返回多个值
1 2 3 4 5 6 |
sub get_site_info() { return ("Unmi", "http://unmi.cc"); } my ($name, $url) = get_site_info(); print "name: $name, url: $url"; |
看样子和 Scala 差不多吗,看起很像是元组的东西,但人家只叫做标量类型
Ruby 的方法返回多个值
1 2 3 4 5 6 7 8 9 10 11 |
def foo return "Unmi", "fantasia@sina.com", "http://unmi.cc" # 或者写成下面的形式 # ["Unmi", "fantasia@sina.com", "http://unmi.cc"] end name, email, url = foo print "name:", name, "\n" #=> name:Unmi print "email:", email, "\n" #=> email:fantasia@sina.com print "url:", url, "\n" #=> url:http://unmi.cc |
在可以 return 逗号隔开的多个值,或是一个数组,使用方式是一样的。
如果要拿 Java 与动态脚本语言比灵活活,显然是极不公平的,但不妨有此方面可以羡慕一下 C# 吧,看
C# 实现方法的多返回值的
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 |
namespace CShareTest { class MainClass { public static void Main (string[] args) { var info = foo (); Console.WriteLine("No: " + info.No + ", Name: " + info.Name); Console.Read(); } public static dynamic foo () { return new{No=100, Name="Unmi"}; } } } |
上面的 C# 代码输出为:
No: 100, Name: Unmi
匿名对象(new {id=100, ...} 这种形式)在 C# 3.5 开始引入,但那些只能作为局部变量使用时才能推断出其中的属性来。自 C# 4.0 之后,匿名对象可以作为方法的返回值来用,返回的类型用 dynamic 标识。
参考:1. .Net 之匿名对象(AnonymousObject)
2. http://www.kuqin.com/rubycndocument/faq/5.html
3. http://www.th7.cn/Program/Perl/2011/08/12/39602.shtml
4. http://ruby-china.org/topics/1847
5. http://www.cnblogs.com/madengwei/archive/2009/03/08/1406260.html
本文链接 https://yanbin.blog/scala-multiple-method-results/, 来自 隔叶黄莺 Yanbin Blog
[版权声明] 本文采用 署名-非商业性使用-相同方式共享 4.0 国际 (CC BY-NC-SA 4.0) 进行许可。