2011-10-25 25 views
5

は、次のコードを考えてみましょう::Scalaの

case class User(id: Int, name: String) 
object User{ 
    def unapply(str: String) = Some(User(0, str)) 
} 

Scalaは、 "エラー:適用を解除する過負荷に解決することはできません;場合、クラスのユーザー(ID:INT、STR:文字列)" 文句 です適用しないでオーバーロードすることはできませんか?

更新: 大きなタプルサイズでは適用を解除します。

case class User(id: Int, str: String) 
object User{ 
    def unapply(s: String) = Some((User(0, s), s, 1234)) 
} 

コンパイラは、まだあなたの適用を解除する方法は

パターンマッチングに使用することができませんでした

答えて

8

一つだけあればそれは

def unapply(arg: <type to match>) : Option[(<matched fields types>)] 

(なしタプルと連携し、「適用解除する過負荷に解決することはできません」文句フィールド、フィールドがない場合はOptionではなくブール値)。あなたが欲しいもの

def unapply(u: User) = 
    if (u eq null) None 
    else Some((u.id, u.name)) 

それを

ユーザーの標準適用解除は次のようになります(Scalaの言語仕様のp。67)は

user match {case User(name) => ....} 

のようにゼロIDを持つユーザーと一致するです

def unapply(u: User): Option[String] = 
    if(u eq null || u.id != 0) None 
    else Some(u.name) 

文字列がユーザーとして一致するようにしたい場合(これはむしろ奇妙です)

def unapply(s: String): Option[User] = Some(User(0, s)) 

それは私はあなたが前者をしたいと思います

"john" match case User(u) => ... // u is User(0, john) 

で動作します。どちらの場合も、あなたのアプリケーションと標準の両方が、同じ引数リスト(Userパラメータ)を持つ2つのメソッドなので互換性はありません。これは、方法は、抽出と呼ばれる場合のように、特徴的な要素は、実際の結果タプルのサイズではなく、引数の型で、少し残念として見ることができます。

ただし、あなたの方法は抽出者としては有効ではありませんが、矛盾は生じません。私はそれを禁じる仕様で何かを見つけることができませんでした。それでも、それは役に立たず、有用な方法は正当に許されません。あなたが適用解除をオーバーライドすることはできません

+0

詳細な説明ありがとうございます! 。で入力中..私はいくつかの使用を逃した私の悪い私は実際に後で1(文字列のうちエキスユーザー)を探しています - 上記の例では、実際のシナリオのオーバー簡素化することがあります。あなたは、区別する要素は実際にはタプルのサイズであると述べましたが、完了のためだけにタプルの結果を追加しようとしましたが、コンパイラは変更しません。どんな考え? – Ajay

+2

あなたはタプルのサイズについて私を誤解しています。私は抽出器の構文を後悔していました。しかし、私は確信していません。一方、文字列入力が必要な場合、なぜそれが許可されないのか分かりません。私がやることは、抽出者に何か他の名前を付けることです。少なくともこの例では、ユーザは非常に誤解を招くので、私は 'オブジェクトNameOfUser {def unapply(s:String):Option [User] ...}'を好むでしょう。あなたのコードに意味があるかどうかわかりません。 –

+0

はい、そうです。私は抽出器に何か他の名前をつけます。しかし、コンパイラのメッセージは意味をなさない。なぜ私がなぜ過負荷をかけることができないのか、どこに矛盾があるのか​​を明確にすべきです。 – Ajay

1

理由は、(特に)、それが自動的にケースクラスのcompantionオブジェクトによって作成されたものと同じsignitureを持っていることをおそらくです。関数の署名は、オーバーライドのための戻り値を考慮に入れていないことに留意してください。