“использование” функции

JavaScript копирует ссылки вместо значений. Если вы хотите скопировать свой head, создайте новый объект head, например:

var newhead = { property1: false, property2: "Something else"}
30
задан Xavier Guihot 31 March 2019 в 12:23
поделиться

5 ответов

Я думал об этом и подумал, что, может быть, есть и другой способ решения этой проблемы. Вот мой взгляд на поддержку «любого числа» параметров (ограниченных тем, что предоставляют кортежи):

object UsingTest {

  type Closeable = {def close():Unit }

  final class CloseAfter[A<:Product](val x: A) {
    def closeAfter[B](block: A=>B): B = {
      try {
        block(x);
      } finally {
        for (i <- 0 until x.productArity) {
          x.productElement(i) match { 
            case c:Closeable => println("closing " + c); c.close()
            case _ => 
          }
        }
      }
    }
  }

  implicit def any2CloseAfter[A<:Product](x: A): CloseAfter[A] = 
    new CloseAfter(x)

  def main(args:Array[String]): Unit = {
    import java.io._

    (new BufferedReader(new FileReader("in.txt")), 
     new PrintWriter("out.txt"),
     new PrintWriter("sample.txt")) closeAfter {case (in, out, other) => 
      out.println(in.readLine) 
      other.println("hello world!")
    }
  }
}

Я думаю, что я повторно использую тот факт, что в библиотеке было написано 22 класса кортежей / продуктов. .. Я не думаю, что этот синтаксис более понятен, чем с использованием nested using (без каламбура), но это была интересная головоломка.

edit: заменил значение val на case (in, out, other), как предлагает retronym.

5
ответ дан huynhjl 28 November 2019 в 00:22
поделиться

Хорошей идеей является отключение алгоритма очистки от пути к программе.

Это решение позволяет накапливать закрываемые объекты в области видимости.
Очистка области будет происходить после выполнения блока, или область может быть отключена. Очистка прицела может быть сделана позже.

Таким образом, мы получаем то же удобство без ограничения однопоточным программированием.

Класс полезности:

import java.io.Closeable

object ManagedScope {
  val scope=new ThreadLocal[Scope]();
  def managedScope[T](inner: =>T):T={
    val previous=scope.get();
    val thisScope=new Scope();
    scope.set(thisScope);
    try{
      inner
    } finally {
      scope.set(previous);
      if(!thisScope.detatched) thisScope.close();
    }
  }

  def closeLater[T <: Closeable](what:T): T = {
    val theScope=scope.get();
    if(!(theScope eq null)){
      theScope.closeables=theScope.closeables.:+(what);
    }
    what;
  }

  def detatchScope(): Scope={
    val theScope=scope.get();
    if(theScope eq null) null;
    else {
      theScope.detatched=true;
      theScope;
    }
  }
}

class Scope{
  var detatched=false;
  var closeables:List[Closeable]=List();

  def close():Unit={
    for(c<-closeables){
      try{
        if(!(c eq null))c.close();
      } catch{
        case e:Throwable=>{};
      }
    }
  }
}

Использование:

  def checkSocketConnect(host:String, portNumber:Int):Unit = managedScope {
    // The close later function tags the closeable to be closed later
    val socket = closeLater( new Socket(host, portNumber) );
    doWork(socket);
  }

  def checkFutureConnect(host:String, portNumber:Int):Unit = managedScope {
    // The close later function tags the closeable to be closed later
    val socket = closeLater( new Socket(host, portNumber) );
    val future:Future[Boolean]=doAsyncWork(socket);

    // Detatch the scope and use it in the future.
    val scope=detatchScope();
    future.onComplete(v=>scope.close());
  }
0
ответ дан Espen Brekke 28 November 2019 в 00:22
поделиться

Начиная с Scala 2.13, стандартная библиотека предоставляет специальную утилиту управления ресурсами: Using .

Более конкретно, Using#Manager можно использовать при работе с несколькими ресурсами.

В нашем случае мы можем управлять различными ресурсами, такими как PrintWriter или BufferedReader , поскольку они оба реализуют AutoCloseable , в порядке читать и записывать из файла в другой и, несмотря ни на что, впоследствии закрыть и входной, и выходной ресурсы:

import scala.util.Using
import java.io.{PrintWriter, BufferedReader, FileReader}

Using.Manager { use =>

  val in  = use(new BufferedReader(new FileReader("input.txt")))
  val out = use(new PrintWriter("output.txt"))

  out.println(in.readLine)
}
// scala.util.Try[Unit] = Success(())
5
ответ дан Xavier Guihot 28 November 2019 в 00:22
поделиться

К сожалению, в стандартном Scala нет поддержки списков параметров произвольной длины с произвольными типами.

Вы могли бы сделать что-то подобное с парой изменений языка (чтобы разрешить передачу списков переменных параметров как HLists; см. здесь примерно 1/3 того, что необходимо).

Прямо сейчас лучше всего просто сделать то, что делают Tuple и Function: реализовать usingN для любого количества N, которое вам нужно.

Два, конечно, достаточно просто:

def using2[A, B <: {def close(): Unit}, C <: { def close(): Unit}](closeB: B, closeC: C)(f: (B,C) => A): A = {
  try { f(closeB,closeC) } finally { closeB.close(); closeC.close() }
}

Если вам нужно больше, вероятно, стоит написать что-то, что будет генерировать исходный код.

2
ответ дан 28 November 2019 в 00:22
поделиться

Вот пример, который позволяет вам использовать scala для понимания в качестве блока автоматического управления ресурсами для любого элемента, который является java.io.Closeable, но его можно легко расширить для работы с любым объектом с помощью метода close.

Это использование кажется довольно близким к оператору using и позволяет легко определять столько ресурсов в одном блоке, сколько вы хотите.

object ResourceTest{
  import CloseableResource._
  import java.io._

  def test(){
    for( input <- new BufferedReader(new FileReader("/tmp/input.txt")); output <- new FileWriter("/tmp/output.txt") ){
      output.write(input.readLine)
    }
  }
}

class CloseableResource[T](resource: =>T,onClose: T=>Unit){
  def foreach(f: T=>Unit){
    val r = resource
    try{
      f(r)
    }
    finally{
      try{
        onClose(r)
      }
      catch{
        case e =>
          println("error closing resource")
          e.printStackTrace
      }
    }
  }
}

object CloseableResource{
  implicit def javaCloseableToCloseableResource[T <: java.io.Closeable](resource:T):CloseableResource[T] = new CloseableResource[T](resource,{_.close})
}
2
ответ дан 28 November 2019 в 00:22
поделиться
Другие вопросы по тегам:

Похожие вопросы: