Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/281.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Scala等价于Python生成器?_Python_Scala - Fatal编程技术网

Scala等价于Python生成器?

Scala等价于Python生成器?,python,scala,Python,Scala,是否可以在Scala中实现与Pythonyield语句等价的东西,在该语句中,它记住使用它的函数的本地状态,并在每次调用它时“生成”下一个值 我想用这样的方法将递归函数转换成迭代器。有点像这样: # this is python def foo(i): yield i if i > 0: for j in foo(i - 1): yield j for i in foo(5): print i 除了,foo可能更复杂,并且通过一些非循环对象图递归 附加编

是否可以在Scala中实现与Python
yield
语句等价的东西,在该语句中,它记住使用它的函数的本地状态,并在每次调用它时“生成”下一个值

我想用这样的方法将递归函数转换成迭代器。有点像这样:

# this is python
def foo(i):
  yield i
  if i > 0:
    for j in foo(i - 1):
      yield j

for i in foo(5):
  print i
除了,
foo
可能更复杂,并且通过一些非循环对象图递归

附加编辑: 让我添加一个更复杂的示例(但仍然很简单): 我可以编写一个简单的递归函数,在运行过程中打印内容:

// this is Scala
def printClass(clazz:Class[_], indent:String=""): Unit = {
  clazz match {
    case null =>
    case _ =>
      println(indent + clazz)
      printClass(clazz.getSuperclass, indent + "  ")
      for (c <- clazz.getInterfaces) {
        printClass(c, indent + "  ")
      }
  }
}
//这是Scala
def printClass(clazz:Class[zz;],indent:String=“”):单位={
克拉兹比赛{
大小写null=>
案例=>
println(缩进+重叠)
printClass(clazz.getSuperclass,缩进+“”)
对于(c)
案例=>
苏多兹

为了(c以一般方式进行此操作,我认为您需要

简单的实现(徒手,未编译/检查):

发生的情况是,对
shift
的任何调用都会捕获从调用它的位置到调用它的
reset
块末尾的控制流。这将作为
k
参数传递到shift函数中

因此,在上面的示例中,每个
giveItUp(x)
返回
x
(到该点为止)的值,并将剩余的计算保存在
state
变量中。它由
hasNext
next
方法从外部驱动


轻点说,这显然是一种糟糕的实现方式。但我最好在深夜不用编译器的情况下完成这项工作。

虽然Python生成器很酷,但在Scala中尝试复制它们并不是最好的方式。例如,以下代码的作用与您想要的相同:

def classStream(clazz:Class[\u]]:Stream[Class[\u]]=clazz匹配{
case null=>Stream.empty
案例=>(
克拉兹
#::类流(clazz.getSuperclass)
#::clazz.getInterfaces.toStream.flatMap(classStream)
#::Stream.empty
)
}
在其中,流是惰性生成的,因此在请求之前不会处理任何元素,您可以通过运行以下命令进行验证:

def classStream(clazz:Class[\u]]:Stream[Class[\u]]=clazz匹配{
case null=>Stream.empty
案例=>(
克拉兹
#:{println(clazz.toString+“:super”);类流(clazz.getSuperclass)}
#:{println(clazz.toString+“:interfaces”);clazz.getInterfaces.toStream.flatMap(classStream)}
#::Stream.empty
)
}
只需在生成的
上调用
.Iterator
,即可将结果转换为
迭代器

def classIterator(clazz: Class[_]): Iterator[Class[_]] = classStream(clazz).iterator
使用
Stream
foo
定义将呈现如下:

scala>def foo(i:Int):Stream[Int]=i#::(if(i>0)foo(i-1)else Stream.empty)
foo:(i:Int)流[Int]
scala>foo(5)foreach println
5.
4.
3.
2.
1.
0
另一种替代方法是连接各种迭代器,注意不要预先计算它们。下面是一个示例,还包含调试消息以帮助跟踪执行:

def yieldClass(clazz: Class[_]): Iterator[Class[_]] = clazz match {
  case null => println("empty"); Iterator.empty
  case _ =>
    def thisIterator = { println("self of "+clazz); Iterator(clazz) }
    def superIterator = { println("super of "+clazz); yieldClass(clazz.getSuperclass) }
    def interfacesIterator = { println("interfaces of "+clazz); clazz.getInterfaces.iterator flatMap yieldClass }
    thisIterator ++ superIterator ++ interfacesIterator
}
这与您的代码非常接近。我没有使用
sudoYield
,而是使用定义,然后按照我的意愿将它们连接起来


因此,虽然这不是一个答案,但我认为你在这里找错了方向。试图用Scala编写Python肯定是徒劳无益的。更努力地使用Scala习惯用法来实现同样的目标。

另一个基于continuations插件的解决方案,这次使用了或多或少封装的生成器类型

import scala.continuations._
import scala.continuations.ControlContext._

object Test {

  def loopWhile(cond: =>Boolean)(body: =>(Unit @suspendable)): Unit @suspendable = {
    if (cond) {
      body
      loopWhile(cond)(body)
    } else ()
  }

  abstract class Generator[T] {
    var producerCont : (Unit => Unit) = null
    var consumerCont : (T => Unit) = null

    protected def body : Unit @suspendable

    reset {
      body
    }

    def generate(t : T) : Unit @suspendable =
      shift {
        (k : Unit => Unit) => {
          producerCont = k
          if (consumerCont != null)
            consumerCont(t)
        }
      }

    def next : T @suspendable =
      shift {
        (k : T => Unit) => {
          consumerCont = k
          if (producerCont != null)
            producerCont()
        }
      }
  }

  def main(args: Array[String]) {
    val g = new Generator[Int] {
      def body = {
        var i = 0
        loopWhile(i < 10) {
          generate(i)
          i += 1
        }
      }
    }

    reset {
      loopWhile(true) {
        println("Generated: "+g.next)
      }
    }
  }
}
导入scala.continuations_
导入scala.continuations.ControlContext_
对象测试{
def loopWhile(cond:=>Boolean)(body:=>(Unit@suspendable)):Unit@suspendable={
如果(秒){
身体
循环时间(秒)(主体)
}else()
}
抽象类生成器[T]{
var producerCont:(单位=>单位)=null
var consumerCont:(T=>Unit)=null
受保护的def主体:单元@suspendable
重置{
身体
}
def生成(t:t):单位@suspendable=
移位{
(k:单位=>单位=>{
producerCont=k
if(consumerCont!=null)
消费者通讯(t)
}
}
def next:T@suspendable=
移位{
(k:T=>单位)=>{
consumerCont=k
如果(producerCont!=null)
producerCont()
}
}
}
def main(参数:数组[字符串]){
val g=新发电机[Int]{
def正文={
变量i=0
loopWhile(i<10){
生成(i)
i+=1
}
}
}
重置{
loopWhile(真){
println(“生成:+g.next”)
}
}
}
}

Scala的for循环的形式
for(e是您正在寻找的

假设您想要创建一个随机数生成器。生成的数字应该存储在一个延迟计算的无限流中,该流可以借助我们内置的特定于域的关键字
Yield
来构建

import com.thoughtworks.dsl.keys.Yield
def xorshiftRandomGenerator(seed: Int): Stream[Int] = {
  val tmp1 = seed ^ (seed << 13)
  val tmp2 = tmp1 ^ (tmp1 >>> 17)
  val tmp3 = tmp2 ^ (tmp2 << 5)
  !Yield(tmp3)
  xorshiftRandomGenerator(tmp3)
}
import com.thoughtworks.dsl.keys.Yield
def xorshift随机生成器(种子:Int):流[Int]={
val tmp1=seed^(seed>>17)

val tmp3=tmp2^(tmp2很难想出一个通过标准技术无法实现的简单示例。例如,我认为您的
yieldClass
示例可以通过使用
迭代器来实现。++
很聪明。但是,是的,我认为
yieldClass
可以通过移位/重置来实现。我不知道什么时候它将不需要插件就可以进入编译器。我认为大多数复杂性都可以分解成一个“生成器库”.我认为Rich Dougherty的博客是这些生物最好的解释来源。关于迭代器,你是对的。++.works。我必须检查Rich的博客。这是一个副本,但奇怪的是,我没有看到原件
import scala.continuations._
import scala.continuations.ControlContext._

object Test {

  def loopWhile(cond: =>Boolean)(body: =>(Unit @suspendable)): Unit @suspendable = {
    if (cond) {
      body
      loopWhile(cond)(body)
    } else ()
  }

  abstract class Generator[T] {
    var producerCont : (Unit => Unit) = null
    var consumerCont : (T => Unit) = null

    protected def body : Unit @suspendable

    reset {
      body
    }

    def generate(t : T) : Unit @suspendable =
      shift {
        (k : Unit => Unit) => {
          producerCont = k
          if (consumerCont != null)
            consumerCont(t)
        }
      }

    def next : T @suspendable =
      shift {
        (k : T => Unit) => {
          consumerCont = k
          if (producerCont != null)
            producerCont()
        }
      }
  }

  def main(args: Array[String]) {
    val g = new Generator[Int] {
      def body = {
        var i = 0
        loopWhile(i < 10) {
          generate(i)
          i += 1
        }
      }
    }

    reset {
      loopWhile(true) {
        println("Generated: "+g.next)
      }
    }
  }
}
case class Countdown(start: Int) extends Traversable[Int] {
    def foreach[U](f: Int => U) {
        var j = start
        while (j >= 0) {f(j); j -= 1}
    }
}

for (i <- Countdown(5))  println(i)
// or equivalent:
Countdown(5) foreach println
  // v1 (without indentation)

  case class ClassStructure(c: Class[_]) {
    def foreach[U](f: Class[_] => U) {
      if (c eq null) return
      f(c)
      ClassStructure(c.getSuperclass) foreach f
      c.getInterfaces foreach (ClassStructure(_) foreach f)
    }
  }

  for (c <- ClassStructure(<foo/>.getClass)) println(c)
  // or equivalent:
  ClassStructure(<foo/>.getClass) foreach println
  // v2 (with indentation)

  case class ClassWithIndent(c: Class[_], indent: String = "") {
    override def toString = indent + c
  }
  implicit def Class2WithIndent(c: Class[_]) = ClassWithIndent(c)

  case class ClassStructure(cwi: ClassWithIndent) {
    def foreach[U](f: ClassWithIndent => U) {
      if (cwi.c eq null) return
      f(cwi)
      ClassStructure(ClassWithIndent(cwi.c.getSuperclass, cwi.indent + "  ")) foreach f
      cwi.c.getInterfaces foreach (i => ClassStructure(ClassWithIndent(i, cwi.indent + "  ")) foreach f)
    }
  }

  for (c <- ClassStructure(<foo/>.getClass)) println(c)
  // or equivalent:
  ClassStructure(<foo/>.getClass) foreach println
class scala.xml.Elem
  class scala.xml.Node
    class scala.xml.NodeSeq
      class java.lang.Object
      interface scala.collection.immutable.Seq
        interface scala.collection.immutable.Iterable
          interface scala.collection.immutable.Traversable
            interface scala.collection.Traversable
              interface scala.collection.TraversableLike
                interface scala.collection.generic.HasNewBuilder
                interface scala.collection.generic.FilterMonadic
                interface scala.collection.TraversableOnce
                  interface scala.ScalaObject
                interface scala.ScalaObject
              interface scala.collection.generic.GenericTraversableTemplate
                interface scala.collection.generic.HasNewBuilder
                interface scala.ScalaObject
              interface scala.ScalaObject
            interface scala.collection.generic.GenericTraversableTemplate
              interface scala.collection.generic.HasNewBuilder
              interface scala.ScalaObject
            interface scala.collection.TraversableLike
              interface scala.collection.generic.HasNewBuilder
              interface scala.collection.generic.FilterMonadic
              interface scala.collection.TraversableOnce
                interface scala.ScalaObject
              interface scala.ScalaObject
            interface scala.Immutable
            interface scala.ScalaObject
          interface scala.collection.Iterable
            interface scala.collection.Traversable
              interface scala.collection.TraversableLike
                interface scala.collection.generic.HasNewBuilder
                interface scala.collection.generic.FilterMonadic
                interface scala.collection.TraversableOnce
                  interface scala.ScalaObject
                interface scala.ScalaObject
              interface scala.collection.generic.GenericTraversableTemplate
                interface scala.collection.generic.HasNewBuilder
                interface scala.ScalaObject
              interface scala.ScalaObject
            interface scala.collection.generic.GenericTraversableTemplate
              interface scala.collection.generic.HasNewBuilder
              interface scala.ScalaObject
            interface scala.collection.IterableLike
              interface scala.Equals
              interface scala.collection.TraversableLike
                interface scala.collection.generic.HasNewBuilder
                interface scala.collection.generic.FilterMonadic
                interface scala.collection.TraversableOnce
                  interface scala.ScalaObject
                interface scala.ScalaObject
              interface scala.ScalaObject
            interface scala.ScalaObject
          interface scala.collection.generic.GenericTraversableTemplate
            interface scala.collection.generic.HasNewBuilder
            interface scala.ScalaObject
          interface scala.collection.IterableLike
            interface scala.Equals
            interface scala.collection.TraversableLike
              interface scala.collection.generic.HasNewBuilder
              interface scala.collection.generic.FilterMonadic
              interface scala.collection.TraversableOnce
                interface scala.ScalaObject
              interface scala.ScalaObject
            interface scala.ScalaObject
          interface scala.ScalaObject
        interface scala.collection.Seq
          interface scala.PartialFunction
            interface scala.Function1
              interface scala.ScalaObject
            interface scala.ScalaObject
          interface scala.collection.Iterable
            interface scala.collection.Traversable
              interface scala.collection.TraversableLike
                interface scala.collection.generic.HasNewBuilder
                interface scala.collection.generic.FilterMonadic
                interface scala.collection.TraversableOnce
                  interface scala.ScalaObject
                interface scala.ScalaObject
              interface scala.collection.generic.GenericTraversableTemplate
                interface scala.collection.generic.HasNewBuilder
                interface scala.ScalaObject
              interface scala.ScalaObject
            interface scala.collection.generic.GenericTraversableTemplate
              interface scala.collection.generic.HasNewBuilder
              interface scala.ScalaObject
            interface scala.collection.IterableLike
              interface scala.Equals
              interface scala.collection.TraversableLike
                interface scala.collection.generic.HasNewBuilder
                interface scala.collection.generic.FilterMonadic
                interface scala.collection.TraversableOnce
                  interface scala.ScalaObject
                interface scala.ScalaObject
              interface scala.ScalaObject
            interface scala.ScalaObject
          interface scala.collection.generic.GenericTraversableTemplate
            interface scala.collection.generic.HasNewBuilder
            interface scala.ScalaObject
          interface scala.collection.SeqLike
            interface scala.collection.IterableLike
              interface scala.Equals
              interface scala.collection.TraversableLike
                interface scala.collection.generic.HasNewBuilder
                interface scala.collection.generic.FilterMonadic
                interface scala.collection.TraversableOnce
                  interface scala.ScalaObject
                interface scala.ScalaObject
              interface scala.ScalaObject
            interface scala.ScalaObject
          interface scala.ScalaObject
        interface scala.collection.generic.GenericTraversableTemplate
          interface scala.collection.generic.HasNewBuilder
          interface scala.ScalaObject
        interface scala.collection.SeqLike
          interface scala.collection.IterableLike
            interface scala.Equals
            interface scala.collection.TraversableLike
              interface scala.collection.generic.HasNewBuilder
              interface scala.collection.generic.FilterMonadic
              interface scala.collection.TraversableOnce
                interface scala.ScalaObject
              interface scala.ScalaObject
            interface scala.ScalaObject
          interface scala.ScalaObject
        interface scala.ScalaObject
      interface scala.collection.SeqLike
        interface scala.collection.IterableLike
          interface scala.Equals
          interface scala.collection.TraversableLike
            interface scala.collection.generic.HasNewBuilder
            interface scala.collection.generic.FilterMonadic
            interface scala.collection.TraversableOnce
              interface scala.ScalaObject
            interface scala.ScalaObject
          interface scala.ScalaObject
        interface scala.ScalaObject
      interface scala.xml.Equality
        interface scala.Equals
        interface scala.ScalaObject
      interface scala.ScalaObject
    interface scala.ScalaObject
  interface scala.ScalaObject
  interface java.io.Serializable
import com.thoughtworks.dsl.keys.Yield
def xorshiftRandomGenerator(seed: Int): Stream[Int] = {
  val tmp1 = seed ^ (seed << 13)
  val tmp2 = tmp1 ^ (tmp1 >>> 17)
  val tmp3 = tmp2 ^ (tmp2 << 5)
  !Yield(tmp3)
  xorshiftRandomGenerator(tmp3)
}