2

我有一个存储在选项中的资源对象。

 private var ochan: Option[Channel] = None

在程序执行期间ochan的某个时刻,设置为Some(channel)。我想关闭通道(通过调用方法close)并将选项设置为None一举致命。

目前我有:

 def disconnect = ochan = { ochan.foreach{_.close}; None }

以前我有:

 def disconnect = ochan = ochan.flatMap{ o => o.close; None }

有一个更好的方法吗?

4

6 回答 6

5

I'd write it like this:

def disconnect = ochan = ochan match {
  case Some(ch) => ch.close(); None
  case None => None // do nothing
}

instead of using foreach or flatMap. In my opinion, this solution shows more clearly and explicitly what happens. The solution with foreach or flatMap requires an extra mental jump, you'd have to know what these methods do on an Option.

于 2011-04-07T21:56:08.990 回答
3

我不知道它更好但它更短(一旦你定义了隐式):

implicit def closer(o: Option[Channel]) = new { 
  def close(): Option[Channel] = { o.foreach(_.close); None } 
}

def disconnect = ochan = ochan.close
于 2011-04-07T21:45:07.597 回答
1

这不是线程安全的!记得使用@volatile(不是这里;使用同步),然后做这样的事情:(这就是我不喜欢命令式代码的原因)

private val lock = new Object

def disconnect() {//Function has side effects: remember parenthesis!
  lock.synchronized { //Synchronizations is important; you don't want to close it multiple times
    ochan.foreach {_.close()} //Again: side effects -> parens.
  }
}

如果你不使用并行编程,你就做错了。

于 2011-04-08T19:08:11.153 回答
1

不可变 var 和可变 val 之间没有太大区别。那么,当您想要具有可变性时,为什么不将行为封装在一个单独的类中呢?

class ChannelOption {
  private var _channel :Option[Channel] = None
  def channel = _channel
  def channel_=(ch:Option[Channel]) { _channel.foreach(_.close); _channel = ch }
}

用法:

private val ochan = new ChannelOption
ochan.channel = Some(getAChannel)
ochan.channel.foreach(useChannel)
ochan.channel = Some(getAnotherChannel) //this automatically closes the first channel
ochan.channel = None //this automatically closes the second channel
于 2011-04-08T06:23:42.720 回答
0

我想这可以工作:

def disconnect { 
  ochan = {
    ochan.get.close
    None
  }
}

或者

def disconnect {
  ochan.get.close
  ochan = None
}

无论如何,由于存在变异操作,它总是需要 2 次调用(1 次用于关闭,1 次用于分配无)。

于 2011-04-07T20:54:10.707 回答
0

您可以定义ochan_=以便分配一个新值来ochan关闭旧通道(类似于std::auto_ptr<>在 C++ 中),但我不知道如何将其封装在子类中,Option[Channel]因为存储在您的类中。该解决方案根本不会改变代码,它只会disconnect通过分配ochan.

于 2011-04-07T20:04:38.290 回答