代码之家  ›  专栏  ›  技术社区  ›  Florian Baierl

使用名称中的空白定义方法

  •  0
  • Florian Baierl  · 技术社区  · 7 年前

    我知道在scala中,我可以这样编写getter/setter:

    class Person() {
     // Private age variable, renamed to _age
     private var _age = 0
     var name = ""
    
     // Getter
     def age = _age
    
     // Setter
     def age_= (value:Int):Unit = _age = value
    }
    

    何处 _ 在里面 def age_= 表示空白。( Source )

    按照这个原则,我想写一些这样的东西:

    
    object SubjectUnderObs {
      var x: Int = 0
    
      private var myListeners : Set[Int => Unit] = Set()
    
      def listeners_+= (listener: Int => Unit): Unit =
        myListeners = myListeners + listener
    }
    
    // This does not compile
    SubjectUnderObs.listeners += { newX =>
      println(newX)
    }
    

    我基本上想使用这种语法添加回调: SubjectUnderObs.listeners += . 然而,在我的例子中,我不能忽略 γ . 为什么这和上面的设置者不一样,我怎样才能实现我想要的呢?

    2 回复  |  直到 7 年前
        1
  •  4
  •   Brian McCutchon    7 年前

    首先,方法以 _= 是表示setter的特殊方法。这就是为什么下划线只能像您认为的那样工作。

    现在,你可以通过公开的方式得到你想要的行为。 var listeners: Set[Int => Unit] 但是人们可以做其他事情,比如删除监听器。您可以让侦听器成为定义 += 方法:

    object listeners {
      def +=(listener: Int => Unit): Unit =
        myListeners += listener
      }
    }
    

    把它放在OBS下的主题里面,它就可以工作了。

        2
  •  2
  •   Luis Miguel Mejía Suárez    7 年前

    没有改变的一般规则 _ 用一个 方法名称。
    在第一个例子中,所发生的是一个语法规则。

    a.b=c等于a.b_u=(c)。在类/对象中创建val/var x时,scala会为您创建方法x和x_u=
    —— Source

    如果你只有这样一个方法 (例如,只有听众) 您可以定义 += 接受 Listener ,我不确定这是否对您足够可读。

    另一个选项是使用嵌套对象提供 DSL 你想要。

    final class SubjectUnderObs { self =>
      private[this] var _listeners: List[Int] = List.empty
    
      object ListenersMutator {
        def += (listener: Int): Unit = {
          self._listeners = listener :: self._listeners
        }
      }
    
      def listeners = ListenersMutator
    
      override def toString: String =
        _listeners.mkString("[", ", ", "]")
    }
    
    val res1 = new SubjectUnderObs
    // res1: SubjectUnderObs = []
    
    res1 += 10
    // res1: SubjectUnderObs = [10]
    
    推荐文章