我试图使用加法和加法乘法成员对Tuple(2)类进行皮条客,这样我就可以更容易地将它们用作几何2D点。这就是我所拥有的:
implicit class Point[+T: Numeric](val t: (T, T)) {
import Numeric.Implicits._
def _1 = t._1
def _2 = t._2
def +[V >: T](p: Point[V])(implicit ev: Numeric[V]) : (V,V) =
(ev.plus(t._1, p._1), ev.plus(t._2, p._2))
}
println((2, 3) + Point(5.0, 6.0))
这不起作用(无法找到ev
),大概是因为严格来说Float
不是Int
的超级类型 - 但是没有&#39 ; t实际上似乎是一个弱一致性运算符,完全不让它意味着我不能再使用ev.plus
因为它期望两个相同类型的值{{1} },而不是V
和T
之一。
如何正确实现此代码?
答案 0 :(得分:1)
你是对的。问题是Numeric[T]
根据其签名V
不允许人们混合使用类型(T
和def plus(x: T, y: T): T
)。
您可以使用/模拟此库: https://github.com/azavea/numeric。它做了许多隐含的体操,允许混合类型工作。
它完全符合您的需求:
EasyImplicits允许您对混合数字类型(例如T + U + Int)进行操作。
或者选择使用基础Double
类型而不是T
/ V
- 我知道这并不总是很好(精度损失等)。
你的代码仍可以使用不混合类型的点,但是Double
看起来并不那么糟糕,因为无论如何都会发生自动转换。
答案 1 :(得分:1)
我相信因为构造函数参数是一个元组,所以它应该简单的数字扩展变得复杂。这涵盖了许多(大多数?)转换。
from concurrent.futures import ThreadPoolExecutor
def wait_on_future():
f = 3
import time
time.sleep(19)
print(f)
with ThreadPoolExecutor(max_workers=2) as executor:
executor.submit(wait_on_future)
print("elo")
用法:
implicit class Point[T: Numeric](a: (T, T)) {
import Numeric.Implicits._
val _1 = a._1
val _2 = a._2
def +(x: T, y: T) = add(_1, _2, x, y)
def +[U: Numeric](x:U, y:U)(implicit ev: T => U) =
add[U](ev(_1), ev(_2), x, y)
def +[U: Numeric](b: Point[U])(implicit ev: T => U) =
add[U](ev(_1), ev(_2), b._1, b._2)
private def add[N: Numeric](a:N, b:N, c:N, d:N) = (a+c, b+d)
}
但它不会将作为参数传递的现有(1, 4) + (2.2, 4.4) //res0: (Double, Double) = (3.2,8.4)
(2.1, 3.1) + (9, 2) //res1: (Double, Double) = (11.1,5.1)
(1, 4) + Point((5.2, 6.2)) //res2: (Double, Double) = (6.2,10.2)
Point((2, 3)) + (4L, 5L) //res3: (Long, Long) = (6,8)
Point((1.5, 2.9)) + (1, 1) //res4: (Double, Double) = (2.5,3.9)
的元素扩展为Point
方法。
+()