留言

留言区

64 thoughts on “留言

    • 核心作者的blog:http://www.chuusai.com/,他们也有个邮件列表,在项目主页可以找到:https://github.com/milessabin/shapeless

  1. 我在gfw的wb下面看到你的博客
    想问个问题
    我在国外,访问www.nicovideo.jp 的时候浏览器会去访问www.x-yao.com,我已经把hosts清空了,也还是不行。但是访问不是www开头的其它页面就没问题,请问到底是怎么回事?ping也ping不过去,全部timeout

    • 我这边访问没有这个问题,你那边可能是 http://www.nicovideo.jp 这个域名被劫持到了www.x-yao.com,你ping的时候这两个网址是否显示同一个ip?尝试刷新一下dns看看:http://cnzhx.net/blog/how-to-flush-dns-cache-in-linux-windows-mac/

  2. hongjiang, 你好!
    关于里氏替换原则的疑惑,求解答:(子类重载父类的方法,需要提供比父类更宽松的参数类型)
    下面是根据里氏替换原则的例子:
    // 作为参数类型使用
    class Parent
    class Child extends Parent
    class GrandChild extends Child

    class Father {
    def func(map: Child) = {
    println(“执行父类…”)
    }
    }

    class Son extends Father {
    def func(map: Parent) = { // 根据里氏替换原则,子类重载父类的方法,需要提供比父类更宽松的参数类型
    println(“执行子类…”)
    }
    }

    object Client extends App {
    val p: Father = new Son
    p.func(new Parent) // 编译出错,type mismatch, expected: Child, actual: Parent
    // 因为p是Father类型的实例,并没有`def func(map: Parent)`方法,所以出错
    p.func(new Child) // 调用了Father类中的`def func(map: Child)`方法,当然可以

    val s: Son = new Son
    s.func(new Parent) // 调用了Son类中的`def func(map: Parent)`方法,当然可以
    s.func(new Child) // 编译出错,ambiguous reference to overloaded definition, both method func in class Son of type (map: Parent)Unit
    // and method func in class Father of type (map: Child)Unit match argument types (Child)
    // 原因是因为s中通过继承父类后存在有`def func(map: Parent)`和`def func(map: Child)`两个方法,
    // s.func(new Child)这种方式调用时,这两个方法都满足,所以编译器不知道到底调用哪一个,就报ambiguous reference to overloaded definition错误
    }

    如果破坏了这个规则:子类重载父类的方法,需要提供比父类更宽松的参数类型

    class Father {
    def func(map: Parent) = {
    println(“执行父类…”)
    }
    }

    class Son extends Father {
    def func(map: Child) = { // 根据里氏替换原则,子类重载父类的方法,提供的参数类型范围比父类的更小
    println(“执行子类…”)
    }
    }

    object Client extends App {
    val p: Father = new Son
    p.func(new Parent) // 编译通过
    p.func(new Child) // 编译通过

    val s: Son = new Son
    s.func(new Parent) // 编译通过
    s.func(new Child) // 编译通过
    }

    居然编译全部通过了。并且s.func(new Child) 的情况,照理说,子类也照样拥有两个方法:`def func(map: Parent)`和`def func(map: Child)`,为什么这个时候,编译的时候,没有报ambiguous reference to overloaded definition错误呢?
    希望能给予回答。谢谢!

    • 你这里的Father和Son里的func并不存在 override 关系,只是子类里定义了一个同名但不同参数的func函数,是overload 不是 override

      • 可能你把好几个感念混淆了,
        1)对象的默认继承关系是“不变”的,而不是“协变”或“逆变”的;要额外显式声明才行。
        2)java/scala里一个方法是由方法名和参数个数/参数类型确定的,参数个数不同或类型不同的话是不同的方法。
        3)函数类型是逆变的,但你的例子不是函数类型

      • hongjiang,你好,谢谢你的回答。

        这里的Father和Son确实就是为了模拟一下里氏替换原则。是重载overload,而非重写override。
        我的困惑是,里氏替换原则为什么要求子类重载父类的方法时,要求方法的参数要比父类的参数类型更宽。
        难道比父类的参数类型窄了。就不能替换父类了么?子类继承自父类,肯定拥有了父类的方法。然后重载一个参数类型更窄的方法时,只是在父类的基础上多了一个属于子类自己的方法而已。这样的话,子类也是照样可以代替父类的,也没有违背里氏替换原则。

        既然没有违背,为什么有子类重载父类的方法时,要求比父类方法参数更宽的类型这个限制呢?
        求解释。

        • overload 是表示同名不同参的方法,跟里氏替代没有任何关系。里氏替代是子类(实现)可以替代父类(接口),行为的替代是通过override体现的。

        • 不明白你描述的LSP具体是在讨论什么,感觉这里混淆的地方可能是在于形参类型(formal parameter types)和参数类型(type parameters)的区别,参见

          Let A1, …, An be the type parameters of M and let B1, …, Bn be the type parameters of N. After renaming each occurrence of a Bi in N’s type to Ai, the bounds of corresponding type variables are the same, and the formal parameter types of M and N are the same.

  3. 王先生您好,我是猎头nick,不好意思打扰了。
    华为正在招聘高端职位,您是他们寻找的候选人之一,请问方便联系吗?期待您的回复。我邮箱是nick.cai@dsi.com.cn。

  4. 请问《Functional Programming in Scala》中文版什么时候才可以买到呢?
    谢谢老师!

    • 内容翻译已经完成,现在在第二次矫正中。但后续流程我不知道要多久。

  5. 您好,本人在美国就读计算机类研究生,最近在上Scala有关的课程,从知乎上找到了您的博客,很多东西写的非常好,本人想做一些文章翻译然后用于与教授同学共享讨论,也可能会发在我自己的博客上,不知道您是否愿意授权于我去做这样的事情。

  6. hongjiang,您好:

    看了《scala在挖财的实践》不由得要竖大拇指,后来想起来一个问题想请教下:akka这部分,当因为数据量越来越大,需要类似集群那样来扩展时,你们在akka这块具体怎么弄的呢?因为听你演讲说没有用akka的集群,所以对这个感到奇怪,特地请教!

    希望能适当深入、具体点,谢谢!

    • 你说的扩展性问题,并不一定要用集群来解决。因为akka的actor本身就支持remote actor,所以当把角色定义清楚,让这些actor之间远程通讯就可以了。集群相对复杂,它除了解决扩展性还解决高可用的问题,在不是非常必要的情况下可以不用引入集群。

      • 谢谢hongjiang,最近在调研akka,想到了这个问题,打算实际验证下,有没有相关好资料推荐下,谢谢!

        • 最好的是官方的文档,可以下载pdf打印成书,也可以搜一下akka相关的书籍,但书籍的版本未必跟得上,要注意。

          • hongjiang,您好:
            官方remote的例子我搞清楚了,但是之后想起来实际的工程应用时,心里还是有疑问,特在此请教:
            以金融行业计息的例子为例,有两个问题:
            1、假如待处理的数据越来越多,一个机器上的actor实例怎么自动扩展来处理越来越多的数据呢?
            2、在超出一台机器处理能力范围之外的数据,创建remote actor的时候,url中包含了远程机器的ip、端口号之类的信息,这样看来扩展时需要技术人员设计、开发等方式的介入,想请教在这样的情况下,有没有什么办法能够自动弹性支撑数据量的扩充呢?

            谢谢!

          • 不好意思,hongjiang:
            还有个问题,很多数据要处理的情况下,为了保证不遗漏,是不是要在一个地方把数据分片后通知到各个负责处理数据的actor,或者由这些actor从一个地方集中获取每个actor处理的数据的范围?
            有没有更好的办法?
            谢谢!

  7. 谢谢hongjiang,
    找到了一个官方的demo,打算好好分析下。回头可能会整理个分析文档。

  8. 您好,我们做培训的,想请您给我们客户做scala-spark方面的培训,您要是有兴趣可以联系我。

  9. 想看看pandora相关的设计思想或者代码,不知道哪里可以找到代码,非常感谢。

  10. 您好,宏江,我是scala爱好者,现居杭州,研究了众多函数式语言之后,觉得凭借scala的能力,将来有没有可能scala会逐渐替代java,成为企业级开发,大数据应用的主流?scala目前还没有在国内普及,阻力到底在哪里?您是scala的专家,想就这个问题和您深入探讨一下。

  11. 宏江你好,
    我是scala的初学者,有个问题想请教一下。scala不是有两种声明变量的方式,var和val,val实际上是声明一个不变的常量。但val好像对array里的元素不起作用,尽管用val声明一个数组,但数组内容一样是可变的:
    //下面是例子:
    scala> val arr = Array(“Hello”, “World!”)
    arr: Array[String] = Array(Hello, World!)
    scala> arr(0) = “Goodby”
    scala> arr
    res25: Array[String] = Array(Goodby, World!)
    scala>
    //
    是不是val对集合不起作用?

    谢谢

    • 这个是基本概念.
      不可变的是 arr引用指向的地址.
      也就是不能再对arr赋值.
      但由于arr指向的是Array, Array可能修改其元素的内容.
      如果你用arr转向一个 immutable.Map, 那么你也是不能修改里面的内容的, 就跟你现在想的一样.

  12. 今天查问题[Scala] 才发现这个宝藏UP.
    速速看了几篇, 每个都能解答我的一些困惑.
    翻了几个交流信息, 原来是阿里的大佬. 现在好像在别的地方发展了. 祝福.

    看了下近一两年, 更新频率好像低了很多. 哪里可以看到up最新的更新呢.

    • 谢谢关注,这几年的人生境况有些多变,没有心思写;稳定下来会继续记录一些所见所闻以及感受。

  13. Scala中国社区还活跃么?网上搜了下发现网址没法访问,或者有微信群么?

Leave a Reply

Your email address will not be published. Required fields are marked *