2014-06-16 4 views
4

Есть ли какой-либо специальный класс case для представления пустого ArrayBuffer, который может использоваться при сопоставлении с образцом, аналогичный Nil для списков?Pattern match empty ArrayBuffer

Кроме того, почему это работает:

scala> collection.mutable.ArrayBuffer.empty == Nil 
res11: Boolean = true 

Хотя это не делает:

scala> collection.mutable.ArrayBuffer() match { case Nil => 1 } 
<console>:8: error: pattern type is incompatible with expected type; 
found : scala.collection.immutable.Nil.type 
required: scala.collection.mutable.ArrayBuffer[Nothing] 

UPDATE

После придав ему некоторые мысли я полагаю, что нет такого случая класса. Хотя существование Nil жизненно важно для работы List, никакой специальной структуры такого рода не требуется для массивов.

Я нашел обходной путь для пустой проверки соответствия, которые могут работать в большинстве случаев:

collection.mutable.ArrayBuffer(2) match { 
    case collection.mutable.ArrayBuffer(v, _*) => v * 2 
    case _ => 0 
} 

Я сначала проверить, если массив имеет по меньшей мере один элемент, а в противном случае он должен быть пустым. Также, как оказалось, я мог бы просто использовать ArrayBuffer.isEmpty вместо соответствия шаблону.

+1

'ArrayBuffer.isEmpty' кажется более правильным для не-ADT! ... или просто 'toList' ваш ArrayBuffer, если это не слишком дорого, и работать над этим. –

ответ

5

Jasper-M предоставил хороший ответ на ваш второй вопрос (почему == работает, но совпадение с образцом не получается).

Что касается вашего первого, то нет эквивалента Nil для ArrayBuffer. Причина в том, что List определяется с использованием понятия scala для алгебраических типов данных (ADT), а ArrayBuffer - нет.

Посмотрите на source на номер ArrayBuffer. Он реализован как обычный класс, тогда как List реализован как абстрактный класс с двумя подклассами: a case objectNil и case class::.

Эти классы case - это то, что позволяет вам сопоставлять рисунок по List. Поскольку нет эквивалента для ArrayBuffer, вы не можете сопоставить шаблон.

+0

Спасибо, что подтвердили мои собственные мысли по этому поводу. – Anton

1
scala> collection.mutable.ArrayBuffer.empty == Nil 
res11: Boolean = true 

Причина это верно, то можно найти, посмотрев на документации equals метода:

верно, если что представляет собой последовательность, которая имеет те же элементы, что и этой последовательности в том же порядке , иначе ложь

например:

scala> val buffer = collection.mutable.ArrayBuffer.empty[Int] 
buffer: scala.collection.mutable.ArrayBuffer[Int] = ArrayBuffer() 

scala> buffer.append(4) 

scala> buffer == List(4) 
res1: Boolean = true 

Так что это не имеет никакого отношения к сопоставлению с образцом.

+0

Кстати, [некоторые люди считают, что scala не имеет понятия типа * safe equals *) (https://stackoverflow.com/questions/19742527/why-has-scala-no-type-safe-equals-method), что не позволит использовать такие вещи, как пример op, или, скажем, '1 == 1.0' –

0

После того, как я подумал, я полагаю, что такого класса дел нет. Хотя существование Nil жизненно важно для работы List, никакой специальной структуры такого рода не требуется для массивов.

Я нашел обходной путь для пустой проверки соответствия, которые могут работать в большинстве случаев:

collection.mutable.ArrayBuffer(2) match { 
    case collection.mutable.ArrayBuffer(v, _*) => v * 2 
    case _ => 0 
} 

Я сначала проверить, если массив имеет по меньшей мере один элемент, а в противном случае он должен быть пустым.

+0

Этот ответ может быть более уместным в качестве редактирования исходного вопроса. Кроме того, почему вы не используете 'ArrayBuffer # isEmpty'? – cdk

+0

Хорошо, тогда я отредактирую свой вопрос. Ничего себе, не знал, что «ArrayBuffer» обладает таким свойством. – Anton

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