2017-01-04 4 views
3

私はこのような配列に一致しようとした:なぜ私はSeq.emptyにマッチできませんか?

val users: Seq[User] = .... 

users match { 
    case Seq.empty => .... 
    case .. 
} 

私が言ってエラーを得た:私はこれを行うことができない理由

stable identifier required, but scala.this.Predef.Set.empty found. 

誰かが説明できますか?すなわちSeq()またはその代わりNilにその背後にある理論

答えて

4

両方Seq.applySeq.emptyunapply方法を持たない、GenericCompanionで実装されているので、あなたはそのパターンマッチングが可能ではないだろうと思うだろうが、Seq.unapplySeq()ので、あなたがSeq()に残ってパターンマッチことができるしている、SeqFactoryに実装それが利用可能になります。 unapplySeq()ドキュメントから

この方法は、パターンマッチ{ケース配列(...)=>}で呼び出されます。

より背景

コレクションは、コンパイラがcase List() => ...のようなものを見たときに呼び出されるメソッドunapplySeq()、経由パターンの可能なマッチングを行います。

それはList(42)はなく、そのパターンマッチングでList.apply(42)と同じものであることは興味深い:

lst match { 
    case List(8)  => ... // OK 
    case List.apply(8) => ... // won't compile 
} 

同じ原理がSeq()Seq.emptyに適用されます。

+0

それで 'Seq.empty'がメソッドであると言うのは本当に正確ではありませんか? –

+2

@ evan058、 'Seq.empty'はメソッドですが、' Seq.apply'もそうです。いくつかのテストを実行した後、いくつかの詳細を追加しました。 – jwvh

+0

Seq.emptyは部分的な関数ではありません。その理由は何ですか? –

2

マッチ:

scala> Seq.empty 
res0: Seq[Nothing] = List() 

scala> val a = Seq(1,2,3) 
a: Seq[Int] = List(1, 2, 3) 

scala> val b = Seq() 
b: Seq[Nothing] = List() 

scala> a match {case Seq() => "empty" 
    | case _ => "other" 
    | } 
res1: String = other 

scala> b match {case Seq() => "empty" 
    | case _ => "other" 
    | } 
res2: String = empty 

はなぜ技術的な理由@jwvh's answerを参照してください。

+0

その値とメソッドの理由 –

+1

部分的ですが、 '()=> Seq()'型(η拡張を使用する場合) 'Seq()'とマッチさせたくないので、 –

+0

@coolbreeze [ @ jwvhの答え](http://stackoverflow.com/a/41474754/2661491)を参照してください。 –

関連する問題