Scala 问题自定义控制结构<->类型参数

发布于 2024-09-30 11:01:34 字数 778 浏览 1 评论 0 原文

我不明白如何在 Scala 中正确应用泛型类型。我已经设法实现了我自己的控制结构(“unless”、“ForEach”),但它们目前仅限于“Int”类型......有谁知道如何更改适用于泛型类型的实现?

实现对我来说并不重要,但我真的想保持现在的控制结构:

import Controls._ 

val Cond = false
val Elements = List(1,2,3)

Unless(Cond) {
  var sum = 0
  ForEach {
    sum += Element 
  } In(Elements) 
  println("The Sum: " + sum)
}

我尝试了几个小时,但我不知道类型参数问题的解决方案。这是我的“Int”有限实现:

object Controls {

  def Unless(cond: => Boolean)(block: => Unit) = {
    if(!cond) block
  }

  var current = 0
  def ForEach(block: => Unit) = {
    new {
      def In(list:List[Int]) = {
        list foreach { i =>
          current = i
          block
        }
      }
    }
  }

  def Element = current

}

非常欢迎任何提示,因为我现在真的陷入困境......

I don´t understand how to apply generic types in Scala correctly. I´ve managed to implement my own control structures ("unless", "ForEach"), but they are limited to "Int" types at the moment... Does anyone know how to change that implementation that works for generic types?!

The implementation doesn´t matter that much for me, but I really want to keep the control structures as they are now:

import Controls._ 

val Cond = false
val Elements = List(1,2,3)

Unless(Cond) {
  var sum = 0
  ForEach {
    sum += Element 
  } In(Elements) 
  println("The Sum: " + sum)
}

I tried it for hours, but I don´t know a solution for the problem with the type parameters. Here´s my "Int" limited implementation:

object Controls {

  def Unless(cond: => Boolean)(block: => Unit) = {
    if(!cond) block
  }

  var current = 0
  def ForEach(block: => Unit) = {
    new {
      def In(list:List[Int]) = {
        list foreach { i =>
          current = i
          block
        }
      }
    }
  }

  def Element = current

}

Any hint´s are very welcome as I´am really stuck right now...

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

清醇 2024-10-07 11:01:34

基本上,您希望在 Unless 块参数内注入定义:

Unless
(Cond)
{ // you want Element available here
  var sum = 0
  ForEach {
    sum += Element 
  } In(Elements) 
  println("The Sum: " + sum)
}

您不能在外部定义它,因为它会提前修复类型。所以我给你两个解决方案。首先,将某些内容注入到块中的传统方法是将其作为参数传递:

Unless(Cond) {
  var sum = 0
  ForEach { Element =>
    sum += Element 
  } In(Elements) 
  println("The Sum: " + sum)
}

您将无法获得单独运行的代码,因为编译器无法推断 元素。因此,这两个更改中的任何一个都是需要的:

  ForEach[int] { Element =>
  ForEach { Element: Int =>

代码如下所示:

object Controls {
  def Unless(cond: => Boolean)(block: => Unit) = {
    if(!cond) block
  }

  def ForEach[T](block: T => Unit) = {
    new {
      def In(list:List[T]) = {
        list foreach block
      }
    }
  }
}

另一个解决方案是创建一个特定于类型的控件的工厂,如下所示:

object Controls {
  def apply[T] = new Controls[T]

  class Controls[T] {
    def Unless(cond: => Boolean)(block: => Unit) = {
      if(!cond) block
    }

    private var current: T = _
    def Element = current
    def ForEach(block: => Unit) = {
      new {
        def In(list:List[T]) = {
          list foreach { i =>
            current = i
            block
          }
        }
      }
    }
  }
}

然后像这样使用它:

val controls = Controls[Int]; import controls._

其余的工作方式与你的例子。

Basically, you want to inject a definition inside the Unless block parameter:

Unless
(Cond)
{ // you want Element available here
  var sum = 0
  ForEach {
    sum += Element 
  } In(Elements) 
  println("The Sum: " + sum)
}

You can't define it outside, because it would fix the type ahead of time. So I'll give you two solutions. First, the traditional way of injecting something into a block is by passing it as a paramter:

Unless(Cond) {
  var sum = 0
  ForEach { Element =>
    sum += Element 
  } In(Elements) 
  println("The Sum: " + sum)
}

You won't be able to get a code that works like that alone, because there is NOTHING available for the compiler to infer the type of Element. So either of these two changes would be needed:

  ForEach[int] { Element =>
  ForEach { Element: Int =>

The code for that would look like this:

object Controls {
  def Unless(cond: => Boolean)(block: => Unit) = {
    if(!cond) block
  }

  def ForEach[T](block: T => Unit) = {
    new {
      def In(list:List[T]) = {
        list foreach block
      }
    }
  }
}

The other solution is to make a factory of type-specific controls, like this:

object Controls {
  def apply[T] = new Controls[T]

  class Controls[T] {
    def Unless(cond: => Boolean)(block: => Unit) = {
      if(!cond) block
    }

    private var current: T = _
    def Element = current
    def ForEach(block: => Unit) = {
      new {
        def In(list:List[T]) = {
          list foreach { i =>
            current = i
            block
          }
        }
      }
    }
  }
}

Then you use it like this:

val controls = Controls[Int]; import controls._

And the rest works just as in your example.

归途 2024-10-07 11:01:34
def ForEach[T](block: => Unit): T = {
    var current: T = _
    new {
        def In(list: List[T]) = {
            list foreach { i =>
                current = i
                block
            }
        }
    }
    current
}

应该做到这一点。

编辑:当您在 ForEach 方法之后使用 current 时,您可能需要更改 ForEach 以返回 current。我编辑了代码片段来反映这一点。

def ForEach[T](block: => Unit): T = {
    var current: T = _
    new {
        def In(list: List[T]) = {
            list foreach { i =>
                current = i
                block
            }
        }
    }
    current
}

Should do the trick.

EDIT: And seeing as you use current after the ForEach method, you may want to change ForEach to return current. I edited the code snippet to reflect this.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文