Примеры использования для потоков в Scala

В Scala существует Потоковый класс, который очень похож на итератор. Различие в теме между Итератором и Потоком в Scala? предложения некоторое понимание сходств и различий между двумя.

Наблюдение, как использовать поток, довольно просто, но у меня нет очень многих общих примеров использования, где я использовал бы поток вместо других артефактов.

Идеи я имею прямо сейчас:

  • Если необходимо использовать бесконечный ряд. Но это не походит на общий пример использования мне так, он не соответствует моим критериям. (Исправьте меня, если это распространено, и у меня просто есть мертвая зона),
  • Если у Вас есть серия данных, где каждый элемент должен быть вычислен, но что можно хотеть снова использовать несколько раз. Это слабо, потому что я мог просто загрузить его в список, которому концептуально легче следовать для большого подмножества населения разработчика.
  • Возможно, существует большой набор данных или в вычислительном отношении дорогого ряда и существует высокая вероятность, что объекты, в которых Вы нуждаетесь, не потребуют посещения всех элементов. Но в этом случае Итератор был бы хорошим соответствием, если Вы не должны делать несколько поисков, в этом случае Вы могли использовать список также, даже если это будет немного менее эффективно.
  • Существует сложная серия данных, которые должны быть снова использованы. Снова список мог использоваться здесь. Хотя в этом случае оба случая было бы одинаково трудно использовать, и Поток будет лучшим соответствием с тех пор не, все элементы должны быть загружены. Но снова не настолько распространенный... или это?

Поэтому я пропустил какое-либо большое использование? Или действительно ли это - предпочтение разработчика по большей части?

Спасибо

50
задан Community 23 May 2017 в 02:16
поделиться

3 ответа

поток - это ITERATOR AS ImmyTable.list состоит в Mutable.List . При благополучности предотвращается, предотвращает класс ошибок, иногда за счет производительности.

Сама SCALAC не невосприимчит к этим проблемам: http://article.gmane.org/gmane.comp.lang.scala.internals/2831

Как указывает Даниэль, благосклонность лени над строгой Упростите алгоритмы и облегчают их составлять.

3
ответ дан 7 November 2019 в 11:04
поделиться

В дополнение к ответу Даниэля, имейте в виду, что поток полезен для короткого замыкания оценки. Например, предположим, что у меня есть огромный набор функций, которые берут string и возврат параметр [String] , и я хочу продолжать выполнять их, пока один из них не работает:

val stringOps = List(
  (s:String) => if (s.length>10) Some(s.length.toString) else None ,
  (s:String) => if (s.length==0) Some("empty") else None ,
  (s:String) => if (s.indexOf(" ")>=0) Some(s.trim) else None
);

, Я, конечно, не хочу выполнить список в целом список , и в списке нет никакого удобного метода , который говорит: «Обработайте это как функции и выполнить их до одного из них Возвращает что-то кроме Нет ». Что делать? Возможно, это:

def transform(input: String, ops: List[String=>Option[String]]) = {
  ops.toStream.map( _(input) ).find(_ isDefined).getOrElse(None)
}

Это принимает список и обрабатывает его как поток (который на самом деле не оценивает ничего), затем определяет новый поток , который является результатом нанесения Функции (но это еще ничего не оценивает и еще не оценивает), то ищет первый, который определяется - и здесь, волшебно, он оглядывается назад и понимает, что он должен применить карту и получить правильные данные из исходного списка - и затем разворачивать его из опции [Опция [String]] на опцию [String] Использование GetOrelse .

Вот пример:

scala> transform("This is a really long string",stringOps)
res0: Option[String] = Some(28)

scala> transform("",stringOps)
res1: Option[String] = Some(empty)

scala> transform("  hi ",stringOps)
res2: Option[String] = Some(hi)

scala> transform("no-match",stringOps)
res3: Option[String] = None

Но работает ли он? Если мы поставят printLn в наших функциях в наши функции, чтобы мы могли сказать, будут ли они вызвать, мы получаем

val stringOps = List(
  (s:String) => {println("1"); if (s.length>10) Some(s.length.toString) else None },
  (s:String) => {println("2"); if (s.length==0) Some("empty") else None },
  (s:String) => {println("3"); if (s.indexOf(" ")>=0) Some(s.trim) else None }
);
// (transform is the same)

scala> transform("This is a really long string",stringOps)
1
res0: Option[String] = Some(28)

scala> transform("no-match",stringOps)                    
1
2
3
res1: Option[String] = None

(это со Scala 2.8; реализация 2.7, к сожалению, 2,7, к сожалению, и обратите внимание Что вы делают накапливаются длинный список , нет , поскольку ваши сбои накапливаются, но предположительно это недорого по сравнению с вашими истинными вычислениями здесь.)

18
ответ дан 7 November 2019 в 11:04
поделиться

Установка «DPLL алгоритма пролитного кода» в Google возвращает этот очень приятный исходный файл в качестве первого результата. Это, вероятно, слишком аккуратно и приятно быть врученным как домашнее задание без обширного отсека и возиться.

http://www.msc.mu.edu/~cstruble/Class/COSC159/SPRING2004/Code/dpll.pl

Второй результат - это эта страница вопроса здесь, как так высоко оценивается.

-121--5044731-

Основное отличие по потоку и а также итератором в том, что последний является смешным и «одним выстрелом», так что говорить, в то время как бывший нет. ITERATOR имеет лучшую площадь памяти, чем поток , но тот факт, что он - это Music, может быть неудобным.

Возьмите этот классический генератор Prime Number, например:

def primeStream(s: Stream[Int]): Stream[Int] =
  Stream.cons(s.head, primeStream(s.tail filter { _ % s.head != 0 }))
val primes = primeStream(Stream.from(2))

Это может быть легко написано с помощью ITERATOR , но итератор не будет Простые числа вычисляются до сих пор.

Итак, один важный аспект потока состоит в том, что вы можете передать его другим функциям, не будучи дублирован первым, или для получения его снова и снова генерировать его.

Что касается дорогих вычислений / бесконечных списков, эти вещи могут быть выполнены с помощью итератора . Бесконечные списки на самом деле довольно полезны - вы просто не знаете этого, потому что у вас этого не было, поэтому вы видели алгоритмы, которые являются более сложными, чем строго необходимыми, просто чтобы справиться с насильственными конечными размерами.

40
ответ дан 7 November 2019 в 11:04
поделиться
Другие вопросы по тегам:

Похожие вопросы: