Pergunta

Temos vindo a perfilar nosso código recentemente e me deparei com alguns hotspots irritantes. Eles estão na forma

assert(a == b, a + " is not equal to " + b)

Porque alguns destes afirma pode ser em código chamado uma enorme quantidade de vezes que o concat string começa a somar. assert é definido como:

def assert(assumption : Boolean, message : Any) = ....

porque não está definido como:

def assert(assumption : Boolean, message : => Any) = ....

Dessa forma, ele iria avaliar preguiçosamente. Dado que não é definido dessa forma há uma maneira em linha de chamar assert com um param mensagem que é avaliada preguiçosamente?

Graças

Foi útil?

Solução

Avaliação preguiçoso tem também alguma sobrecarga para o objeto função criada. Se o seu objeto de mensagem já está totalmente construído (uma mensagem estática) essa sobrecarga é desnecessário.

O método apropriado para seu caso de uso seria sprintf-style:

assert(a == b,  "%s is not equal to %s", a, b)

Enquanto não é uma função speciaized

assert(Boolean, String, Any, Any)

esta implementação tem nenhuma sobrecarga ou o custo da matriz var args

assert(Boolean, String, Any*)

para o caso geral.

Implementação toString seria avaliada preguiçosamente, mas não é legível:

assert(a == b, new { override def toString =  a + " is not equal to " + b })

Outras dicas

É por nome, eu mudei mais de um ano atrás.

http://www.scala-lang.org/node/825

predef atual:

@elidable(ASSERTION)
def assert(assertion: Boolean, message: => Any) {
  if (!assertion)
    throw new java.lang.AssertionError("assertion failed: "+ message)
}

resposta Thomas' é grande, mas apenas no caso de você gosta da idéia da última resposta, mas não gostam da ilegibilidade, você pode obter em torno dele:

object LazyS {
  def apply(f: => String): AnyRef = new {
    override def toString = f
  }
}

Exemplo:

object KnightSpeak {
  override def toString = { println("Turned into a string") ; "Ni" }
}

scala> assert(true != false , LazyS("I say " + KnightSpeak))

scala> println( LazyS("I say " + KnightSpeak) )
Turned into a string
I say Ni

Tente: assert( a==b, "%s is not equals to %s".format(a,b)) O formato deve ser chamado somente quando o assert precisa da string. Formato é adicionado ao RichString via implícita.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top