scala中的this.type

本文探讨Scala中Parser的实现方式,解析复杂语法糖背后的工作原理,特别是`~`操作符和`this.type`的使用技巧。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

自从开始看scala的Parser相关的源码以来,我越来越觉得scala中很多处理方法就像是用黑魔法在与编译器打交道。不变成JVM上的c++誓不罢休?

 

看Programming in Scala 源码 33.6

abstract class Parser[+T] ... { p =>
...
  def ~ [U](q: => Parser[U]) = new Parser[T~U] {
  def apply(in: Input) = p(in) match {
    case Success(x, in1) =>
      q(in1) match {
         case Success(y, in2) => Success(new ~(x, y), in2)
         case failure => failure
      }
    case failure => failure
  }
}

 结果查2.9.1里的代码

def ~ [U](q: => Parser[U]): Parser[~[T, U]] = { lazy val p = q // lazy argument
      (for(a <- this; b <- p) yield new ~(a,b)).named("~")
    }

 named方法的定义

def named(n: String): this.type = {name=n; this}

 对这个地方一直不明白,查到了这篇文章 后才了解到它的作用。

  class A {def method1: A = this }
  class B extends A (def method2: B = this}
  val b = new B

如果调用b.method2.method1是可以的,但是如果想调用b.method1.method2就不行了。因为method1返回的是A类型的。

当然你可以在B中覆盖method1,以返回正确类型。但是scala中解决这个问题的办法就是this.type

class A { def method1: this.type = this }
class B extends A { def method2: this.type = this }
val b = new B

如果调用b.method1则编译器会知道method1返回的是B类型的。

 

自言自语:

    scala学习曲线过高,代码可读性差(也许我读得还不够多),大量的语法规则和复杂的类型申明让我头晕。是不是该继续尝试更为纯粹的clojure呢?

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值