Scala 用元组/列表类型实现多返回值的函数

Java 的方法不支持多返回值,或者我们想达到返回多个值的效果时,不得不借用数组、列表或对象等来容纳多个值返回给调用者。这样使用起来不怎么优美,特别是为返回多个值而创造一个类成本有点高,如果 Java 也存在像 C# 那样的匿名类倒好。C# 如何使用匿名类返回多个值可参看本文后面的例子。


把 Scala 当作是一种脚本语言,它的灵活性就应该与 Perl 或 Ruby 看齐。Scala 的方法也可以有多个返回值,它实现些种行为,可借助于元组和列表类型,虽然你也可以发掘更多的实现方式,但到目前为止,我还是觉得用元组和列表最简单。

下面给出代码例子,让我们瞧瞧 Scala 如何实现方法多个返回值,并且作为对比我还会贴上 Perl, Ruby 和 C# 可以怎么实现多返回值。我是 Java 的惯用者,不过我一直都未否认,从语言层面 C# 比 Java 要显得优雅的多。

用元组实现 Scala 方法多返回值:

1def foo = (100, "Unmi") //定义方法返回元组
2
3val (num, name) = foo //用元组模式去接收方法 foo 的结果
4println(num + ":" + name) //输出为 100:Unmi
5
6val values = foo //调用方法的结果直接给元组变量
7println(values._1 + ":"+ values._2) //输出同样是  100:Unmi

方法返回一个元组,里面可以组合任何多个的不同类型的返回值,调用时可以用元组变量或元组模式去接收方法的返回值,用元组模式的方式更好看些,也才能算作真正的多返回值。

用 List 实现 Scala 方法多返回值

1def bar = List(100, "Unmi", "http://unmi.cc") //定义方法返回列表
2val List(id, name, url) = bar
3println("id: " + id + ", name: " + name + ", url: " + url)

上面用的是列表模式来接收返回列表的方法,这样达到对返回的列表元素的拆解。如果直接用列表变量来接收返回值,那么这与 Java 中用返回多个值组成的数组就没有一点区别了。

接下来我们来观摩一下 Perl, Ruby 和 C# 是怎么做到返回多个值的

Perl 的子过程返回多个值

1sub get_site_info() {
2    return ("Unmi", "http://unmi.cc");
3}
4
5my ($name, $url) = get_site_info();
6print "name: $name, url: $url";

看样子和 Scala 差不多吗,看起很像是元组的东西,但人家只叫做标量类型

Ruby 的方法返回多个值

 1def foo
 2  return "Unmi", "fantasia@sina.com", "http://unmi.cc"
 3  
 4  # 或者写成下面的形式
 5  # ["Unmi", "fantasia@sina.com", "http://unmi.cc"]
 6end
 7
 8name, email, url = foo
 9print "name:", name, "\n" #=> name:Unmi
10print "email:", email, "\n" #=> email:fantasia@sina.com
11print "url:", url, "\n" #=> url:http://unmi.cc

在可以 return 逗号隔开的多个值,或是一个数组,使用方式是一样的。

如果要拿 Java 与动态脚本语言比灵活活,显然是极不公平的,但不妨有此方面可以羡慕一下 C# 吧,看

C# 实现方法的多返回值的

 1namespace CShareTest
 2{
 3    class MainClass
 4    {
 5        public static void Main (string[] args)
 6        {
 7            var info = foo ();
 8            Console.WriteLine("No: " + info.No + ", Name: " + info.Name);
 9            Console.Read();
10        }
11
12        public static dynamic foo ()
13        {
14            return new{No=100, Name="Unmi"}; 
15        }
16    }
17}

上面的 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's Blog
[版权声明] 本文采用 署名-非商业性使用-相同方式共享 4.0 国际 (CC BY-NC-SA 4.0) 进行许可。