本文介绍了scala是否提供类似C ++模板的东西?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述



考虑下面的C ++模板类:

 模板< class T> 
class Point2
{
Point2(T x,T y):
x(x),
y(y)
{}

T x;
T y;
Point2< T> operator +(Point< T> const& other)const
{
return Point< T>(x + other.x,y + other.y);
}
T sumComponents()const {return x + y; }
}

Point2< Double> p0(12.3,45.6)
Point2< Double> p1(12.3,45.6)
Point2< Double> p = p1 + p2
Double d = p1.sumComponents()

我想写这样的东西:

  case class Point2 [T](x:T,y:T){
def +()Point2 [T]:= x + y
def sumComponents()T:= x + y
}

或(因为编译有问题),

  trait可添加[T] {//需要T支持+操作
def +(that:T):T
}
case class Point2 [T def +()Point2 [T]:= x + y
def sumComponents()T:= x + y
}

这同样存在问题,因为我不能要求Double扩展Addable。





实现上述的惯用方法是什么? Scala呢?

对于C ++模板程序员来说,理解scala中泛型极限的正确方法是什么? (为什么不能在scala中执行此操作?例如,是因为泛型是在实例化之前编译的吗?)

解决方案 div>

我创建了一个库。您可以使用该库创建C ++风格的模板,避免复杂隐式 s。

  import com.thoughtworks.template 
case class Point2 [T](x:T,y:T){
@template def +(rhs:Point2 [_])= Point2(x + rhs.x,y + rhs.y)
@template def sumComponents()= x + y
}

println(Point2(1,3).sumComponents()) //输出:4
println(Point2(1,3)+ Point2(100,200))//输出:Point2(101,203)

请注意,您甚至可以使用不同的组件类型加上两个 Point2 s。

  println(Point2(1.5,0.3)+ Point2(100,200))//输出:Point2(101.5,200.3)

即使嵌套 Point2

<$ p (点2(0.1,0.2),点2(1.0,2.0))点数2(点2(10.1,20.2),点2(101.0,202.0))
println )+ Point2(Point2(10,20),Point2(100,200)))

因为 @template 函数是将在调用站点内联的代码模板。


I'm coming from C++ and trying to wrap my head around scala's type system.

Consider the following C++ template class:

template<class T>
class Point2
{
  Point2( T x, T y ) :
     x(x),
     y(y)
  {}

  T x;
  T y;
  Point2<T> operator+( Point<T> const& other ) const
  {
     return Point<T>(x+other.x, y+other.y);
  }
  T sumComponents() const { return x+y; }
}

Point2<Double> p0(12.3, 45.6) 
Point2<Double> p1(12.3, 45.6) 
Point2<Double> p = p1+p2
Double d = p1.sumComponents()

I'm finding I want to write something like this:

case class Point2[ T ] (x:T, y:T) {
   def +() Point2[T]: = x+y
   def sumComponents() T: = x+y
}

or, (because the compile has problems with this),

trait Addable[T] {   // Require T supports the + operatory
   def +( that:T ):T
}
case class Point2[ T<:Addable[T] ] (x:T, y:T) {
   def +() Point2[T]: = x+y
   def sumComponents() T: = x+y
}

which is similarly problematic because I can't require Double to extend Addable.

Generally, I'm finding it scala's type system works with a set of constraints that I don't quite understand.

What's the idiomatic way of implementing the above in scala?

And what's the right way for C++ template programmers to understand the limits of generics in scala? (why can't I do this in scala? e.g. Is it because generics are compiled before being instaniated?)

解决方案

I created a library template.scala. You can use the library to create C++ flavored templates, avoiding complicated implicits.

import com.thoughtworks.template
case class Point2[T](x:T, y:T) {
   @template def +(rhs: Point2[_]) = Point2(x + rhs.x, y + rhs.y)
   @template def sumComponents() = x + y
}

println(Point2(1, 3).sumComponents()) // Output: 4
println(Point2(1, 3) + Point2(100, 200)) // Output: Point2(101,203)

Note that you can even plus two Point2s with different component types.

println(Point2(1.5, 0.3) + Point2(100, 200)) // Output: Point2(101.5,200.3)

Even nested Point2:

// Output: Point2(Point2(10.1,20.2),Point2(101.0,202.0))
println(Point2(Point2(0.1, 0.2), Point2(1.0, 2.0)) + Point2(Point2(10, 20), Point2(100, 200)))

It works because @template functions are code templates that will inline at the call site.

这篇关于scala是否提供类似C ++模板的东西?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

11-02 16:55