2013-09-17 2 views
4
исключить его

У меня есть случай из класса библиотеки, и я хочу, чтобы переопределить метод unapply, чтобы уменьшить число параметров мне нужно пройти, чтобы сделать поиск по шаблону против него. Я делаю это:Перекрытие метод

object ws1 { 
    // a library class 
    case class MyClass(a: Int, b: String, c: String, d: Double /* and many more ones*/) 

    // my object I created to override unapply of class MyClass 
    object MyClass { 
    def unapply(x: Int) = Some(x) 
    } 

    val a = new MyClass(1, "2", "3", 55.0 /* and many more ones*/) 
    a match { 
    case MyClass(x /*only the first one is vital*/) => x // java.io.Serializable = (1,2,3,55.0) 
    case _ => "no" 
    } 
} 

Но я хочу, чтобы вернуться только 1. Что случилось с этим?

ответ

6
case class MyClass(a: Int, b: String, c: String, d: Double /* and many more ones*/) 
object MyClassA { 
    def unapply(x: MyClass) = Some(x.a) 
} 

val a = new MyClass(1, "2", "3", 55.0 /* and many more ones*/) 

a match { 
    case MyClassA(2) => ??? // does not match 
    case MyClassA(1) => a // matches 
    case _ => ??? 
} 

Вы ча nnot определите свой собственный метод unapply в объекте MyClass, потому что он должен принять параметр MyClass, и там уже есть один такой метод - один, который автоматически генерируется для класса case. Поэтому вы должны определить его в другом объекте (MyClassA в этом случае).

Соответствие шаблону в Scala принимает ваш объект и применяет к нему несколько методов unapply и unapplySeq, пока оно не получит Some со значениями, соответствующими указанным в шаблоне.
MyClassA(1) соответствует a, если MyClassA.unapply(a) == Some(1).

Примечание: если бы я написал case m @ MyClassA(1) =>, то переменная m имела бы тип MyClass.

Edit:

a match { 
    case MyClassA(x) => x // x is an Int, equal to a.a 
    case _ => ??? 
} 
+0

, почему он возвращает Any в случае a или d? –

+0

Не могли бы вы опубликовать фрагмент, который вызывает проблему? –

+0

@Grienders Возвращает Любое из-за вашего случая по умолчанию, в котором указано возвращаемое значение «нет». Поскольку один случай возвращает Int и другую String, ближайший общий суперкласс для результата совпадения - Any. – Shadowlands

2

Я бы канавы перегружен и просто исключить его использовать следующий за матч:

a match { 
    case MyClass(x, _, _, _) => x // Result is: 1 
    case _ => "no" 
} 

EDIT:

Если вы действительно хотите, чтобы избежать лишних подчёркивания, я думаю, что вам нужно смотреть на что-то вроде:

a match { 
    case x:MyClass => x.a 
    case _ => "no" 
} 
+0

Это хочу, я не хочу делать, поэтому я решил отменить исключить его. –

+0

Почему ты этого не хочешь? Как насчет этого не работает для вас? – Shadowlands

+0

Я обновил вопрос. –

Смежные вопросы