2017-09-29 17 views
4

文字列からオブジェクトを抽出する抽出機能を持っています。パターンマッチングと部分関数の適用外関数の相違点

case class ItemStructure(id: String, data: String) 
object ItemStructure { 
    def unapply(str: String): Option[ItemStructure] = { 
    str.split('-').toList match { 
     case List(id, data) => Some(ItemStructure(id, data)) 
     case _    => None 
    } 
    } 
} 

パターンマッチングでこのエクストラクタを使用しようとすると、すべて正常に動作します。

"" match { 
    case ItemStructure(item) => 
} 

また、匿名関数と一致するパターンでも動作します。私は部分的な機能で、この抽出器を使用しようと

Option("").map { 
    case ItemStructure(item) => 
} 

は今、コンパイラはメッセージで失敗します。私は、適用を解除する機能があるコンパニオンオブジェクトの名前を変更する場合は適用を解除する

val func: PartialFunction[Any, Unit] = { 
    case ItemStructure(item) => 
} 

過負荷に解決することはできませんそれからすべてが期待どおりに動作します。

コンパニオンオブジェクトに含まれていると抽出が機能しない理由を誰かが説明できますか?

答えて

4

2つのItemStructure.unapplyメソッドがあります。ケースクラスによって作成されたメソッドと、自分で作成したメソッドです。前者はタイプItemStructure、後者はタイプStringの引数をとります。

最初の2つの例では、一致するオブジェクトのタイプはStringなので、2番目のunapplyメソッドのみを適用でき、曖昧さはありません。しかし、最後の例では、unapplyの両方のメソッドが修飾されるため、Scalaはどちらを使用するのかを知りません。

unapplyメソッドをコンパニオンオブジェクト以外の場所に配置すると、2つのunapplyメソッドはなくなります(他のオブジェクトがコンパニオンオブジェクトにまだ存在するため)。したがって、あいまいさを解決する:ItemStructure.unapplyは明らかに自動生成されたunapplyを指し、NewName.unapplyはあなたのことを明確に表しています。

+0

最後の例が両方の未適用メソッドにどのように適合しているか理解できませんでした。あなたもそれを説明できますか? – fcat

+0

@fcat型がStringの場合、 'unapply(ItemStructure)'は決してマッチできないので、考慮する必要はありません。型が 'ItemStructure'の場合、' unapply(String) 'は決してマッチできません。型が 'Any'の場合、' Any'は 'ItemStructure'か' String'である可能性があるので、どちらも一致します。 – sepp2k

+0

私は最後のもののタイプが 'Any'であることを知りません。説明ありがとう! – fcat

2

Any結果タイプとして、コンパイラはどこから未適用関数を取り出すべきかを特定できません。 unappl yは、Stringタイプの動作のみを定義します。

しかしこれは動作します:

val func: PartialFunction[String, Unit] = { 
    case ItemStructure(item) => 
} 

をそれ以外のタイプAnyをとる適用を解除する関数を定義してみてください。

+0

@ sepp2kから回答が受け付けられました。 – akkie

関連する問題