FAQ
杨博的改法能编译就好。我只是随手写了一下代码说思路,没有真正去测过的 :-)


2014-04-28 15:05 GMT+08:00 杨博 <pop.atry@gmail.com>:
在 2014年4月28日 下午2:39,Nicholas Ren <nicholas85211@gmail.com>写道:
草原老师的方案1,在我这儿还是编译不通过:

class Adder[A <: Plusable] extends Computer[A] {
def compute(x: A, y: A): A = x + y //此行出错
必须改成def compute(x: A, y: A): A = (x + y).asInstanceOf[A]

}
type mismatch;
found : A$A3.this.Plusable
required: A
def compute(x: A, y: A): A = x + y
^

方案2,也编译失败:
error: type mismatch;
found : Any
required: A
def compute(x:A, y:A): A = x + y
^

对于第一种方案, 我的理解是,定义一个支持`+`操作的Plusable
trait,把Adder的类型参数A的上界设置为Plustable,通过类型上界限定A能够支持`+`操作,然而却编译失败,不理解。

对于第二种方案,Structural Type不了解。

杨博的方案通过隐式转换解决了`+`操作找不到的问题,很漂亮。但是我仍然很想知道草原老师的方案一为啥在我这儿编译失败。

--
Nicholas Ren (任晓君)

*Thought*Works | Xi'an | GMT+8

On Monday, April 28, 2014 at 1:58 PM, 杨博 wrote:

草原哥的写法不错。我再补充个更符合Scala惯例的非侵入做法,不需要修改A的实现,而只要给A添加能隐式找到的助手类就可以了:

def compute[A](x:A, y:A)(implicit numeric: Numeric[A]):A = {
import numeric._
x + y
}
assert(compute(1, 2) == 3)
assert(compute(1.2, 3.4) == 4.6)

那个Computer基类看着扎眼,我给删了。

在 2014年4月24日星期四UTC+8下午4时04分46秒,Caoyuan写道:

你这样当然编译不过,就像Liu Sam说的,A没有任何它具有+这个接口的信息。

方案1:
trait Plusable {
def +(x: Plusable): Plusable
}

trait Computer[A <: Plusable] {
def compute(x:A, y:A):A
}

class Adder[A <: Plusable] extends Computer[A] {
def compute(x:A, y:A): A = {
x + y // 无法编译,提示类型不正确
}
}

方案2,使用Structural Type

type Plusable = {
def +(x: Any): Any
}

trait Computer[A <: Plusable] {
def compute(x:A, y:A):A
}

class Adder[A <: Plusable] extends Computer[A] {
def compute(x:A, y:A): A = {
x + y // 无法编译,提示类型不正确
}
}


方案1中所有的A必须实现Plusable,这是一种静态强约束。
方案2中所有的A只要有def +(x: Any): Any方法即可,不必扩展成Plusable(Plusable只是一个别名),
但运行时在JVM中是采用反射实现的,运行性能会受影响。


2014-04-24 11:10 GMT+08:00 Xiang Zhang <solom...@gmail.com>:

我不太了解scala,但是在F#中,这种情况需要用到inline, 泛型的类型和C++中模板类型参数是不同的,
泛型中的类型是runtime类型,编译期无法决定,所以你必须对泛型类型有所约束,比如添加constraints,要求有某些静态方法。


2014-04-24 9:31 GMT+08:00 Liu Sam <world...@gmail.com>:

还有报错,不好意思,试试这样:

object Hello extends App {

println("Hello World!")
val adder:Adder[Int] = new Adder[Int]
println(adder.compute(9, 3))
val addstr:Adder[String] = new Adder[String]
println(addstr.compute("fd", "df"))
}

trait Computer[A] {
def compute(x:A, y:A):A = {
x
}
}

class Adder[A] extends Computer[A] {
def compute(x:Int, y:Int):Int = {
x + y
}
def compute(x:String, y:String):String = {
x + y
}
}

Best regards!

Sam Liu
world...@gmail.com



在 2014年4月24日,上午9:28,Liu Sam <world...@gmail.com> 写道:

如果需求是传入不同类型的对象,执行不同的加法,则可以具体实现如下:

trait Computer[A] {
def compute(x:A, y:A):A
}

class Adder[A] extends Computer[A] {
def compute(x:Int, y:Int):Int = {
x + y
}
def compute(x:String, y:String):String = {
x + y
}
}

Best regards!

Sam Liu
world...@gmail.com



在 2014年4月24日,上午9:21,Liu Sam <world...@gmail.com> 写道:

似乎是说这样写太泛了,呵呵……谁能保证 A 这个 Any 类型的对象一定有“+”这个方法呢?
这个问题的准确需求是什么呢?

Best regards!

Sam Liu
world...@gmail.com



在 2014年4月19日,下午6:12,Fei Wang <pyth...@gmail.com> 写道:

trait Computer[A] {
def compute(x:A, y:A):A
}

class Adder[A] extends Computer[A] {
def compute(x:A, y:A): A = {
x + y // 无法编译,提示类型不正确
}
}

这里为什么会出现类型不正确呢?需要对x和y做类型限定吗,他们必须能做加运算?应该怎么改呢

--
您收到此邮件是因为您订阅了Google网上论坛中的“Scala中文社区”论坛。
要退订此论坛并停止接收此论坛的电子邮件,请发送电子邮件到scalacn+unsubscribe@googlegroups.com
要发帖到此论坛,请发送电子邮件至sca...@googlegroups.com。
要查看更多选项,请访问https://groups.google.com/d/optout。




--
您收到此邮件是因为您订阅了Google网上论坛中的“Scala中文社区”论坛。
要退订此论坛并停止接收此论坛的电子邮件,请发送电子邮件到scalacn+unsubscribe@googlegroups.com
要发帖到此论坛,请发送电子邮件至sca...@googlegroups.com。
要查看更多选项,请访问https://groups.google.com/d/optout。


--
您收到此邮件是因为您订阅了Google网上论坛中的“Scala中文社区”论坛。
要退订此论坛并停止接收此论坛的电子邮件,请发送电子邮件到scalacn+unsubscribe@googlegroups.com
要发帖到此论坛,请发送电子邮件至sca...@googlegroups.com。
要查看更多选项,请访问https://groups.google.com/d/optout。


--
您收到此邮件是因为您订阅了Google网上论坛中的“Scala中文社区”论坛。
要退订此论坛并停止接收此论坛的电子邮件,请发送电子邮件到scalacn+unsubscribe@googlegroups.com
要发帖到此论坛,请发送电子邮件至scalacn@googlegroups.com
要查看更多选项,请访问https://groups.google.com/d/optout。


--
您收到此邮件是因为您订阅了Google网上论坛“Scala中文社区”中的主题。
要退订此主题,请访问
https://groups.google.com/d/topic/scalacn/wAyj7aYtocg/unsubscribe。
要退订此论坛及其所有主题,请发送电子邮件到scalacn+unsubscribe@googlegroups.com

要发帖到此论坛,请发送电子邮件至scalacn@googlegroups.com
要查看更多选项,请访问https://groups.google.com/d/optout。


--
杨博 (Yang Bo)

--
您收到此邮件是因为您订阅了Google网上论坛中的“Scala中文社区”论坛。
要退订此论坛并停止接收此论坛的电子邮件,请发送电子邮件到scalacn+unsubscribe@googlegroups.com
要发帖到此论坛,请发送电子邮件至scalacn@googlegroups.com
要查看更多选项,请访问https://groups.google.com/d/optout。
--
您收到此邮件是因为您订阅了 Google 网上论坛的“Scala中文社区”论坛。
要退订此论坛并停止接收此论坛的电子邮件,请发送电子邮件到scalacn+unsubscribe@googlegroups.com
要向此网上论坛发帖,请发送电子邮件至 scalacn@googlegroups.com
要查看更多选项,请访问 https://groups.google.com/d/optout。

Search Discussions

Discussion Posts

Previous

Follow ups

Related Discussions

Discussion Navigation
viewthread | post
posts ‹ prev | 10 of 11 | next ›
Discussion Overview
groupscalacn @
postedApr 24, '14 at 12:05a
activeApr 28, '14 at 10:02a
posts11
users6

People

Translate

site design / logo © 2019 Grokbase