Empresas
Empregos
  • Sobre nós
  • Soluções
    • Publicação de vagas
      Publique sua vaga e receba candidatos qualificados em 48h.
    • Avaliações de candidatos
      Mais de 500 testes técnicos e psicológicos, mais anti-fraude.
    • Headhunting
      Busca executiva personalizada do início ao fim.
    • Folha de Pagamento + EOR
      Dispersão de folha e EOR em mais de 15 países da LATAM.
  • Preços
  • Empregos

0

250
Visualizações
Scala: acceso a parámetros de clase frente a acceso a campos de objetos

Vengo de experiencia en Java y soy nuevo en Scala, actualmente estoy leyendo el libro 'Programación en Scala'.

Hay un ejemplo en el libro de la siguiente manera:

 class Rational(n: Int, d: Int) { // This won't compile require(d != 0) override def toString = n + "/" + d def add(that: Rational): Rational = new Rational(n * that.d + that.n * d, d * that.d) }

Sin embargo, dado este código, el compilador se queja:

 error: value d is not a member of Rational new Rational(n * that.d + that.n * d, d * that.d) ^ error: value n is not a member of Rational new Rational(n * that.d + that.n * d, d * that.d) ^ error: value d is not a member of Rational new Rational(n * that.d + that.n * d, d * that.d) ^

La explicación dice:

Aunque los parámetros de clase n y d están dentro del alcance del código de su método add, solo puede acceder a su valor en el objeto en el que se invocó add. Por lo tanto, cuando dice n o d en la implementación de add, el compilador se complace en proporcionarle los valores para estos parámetros de clase. Pero no le permitirá decir that.n o that.d porque eso no se refiere al objeto de Rational en el que se invocó add. Para acceder al numerador y al denominador en eso, deberá convertirlos en campos.

También la implementación correcta se da a continuación:

 class Rational(n: Int, d: Int) { require(d != 0) val numer: Int = n val denom: Int = d override def toString = numer + "/" + denom def add(that: Rational): Rational = new Rational( numer * that.denom + that.numer * denom, denom * that.denom ) }

Traté de entender esto muchas veces, pero todavía no estaba claro.

Ya tengo los parámetros n y d a nivel de clase. Puedo acceder a ellos en el método add . Estoy pasando otro objeto de Rational al método add . También debería tener n y d , ¿verdad?

¿Qué hay de malo en that.n y that.d ? ¿Por qué necesito tomar los parámetros en los campos?

Además, el método toString anulado simplemente está tomando n y d , ¿cómo no falla eso?

Puedo sonar estúpido, pero realmente necesito entender esto claramente para obtener mejores fundamentos antes de seguir adelante.

about 4 years ago · Santiago Trujillo
3 Respostas
Responde à pergunta

0

Los parámetros que se pasan a un constructor de clase tienen como valor predeterminado miembros privados y, por lo tanto, están disponibles para todo el código de clase (como se ve en la anulación de toString ), pero no se puede acceder a ellos como miembros de instancia (por lo que that.d no funciona).

Puede decirle al compilador que no use el valor predeterminado.

 class Rational(val n: Int, val d: Int) { // now it compiles ...

Alternativamente, los argumentos que se pasan a una case class de forma predeterminada a los miembros de la instancia.

 case class Rational(n: Int, d: Int) { // this also compiles ...
about 4 years ago · Santiago Trujillo Relatório

0

Scala tiene más tipos de modificadores de acceso que Java. En Scala hay algo llamado private[this] que significa "privado para el objeto actual" que es más estricto que el private normal que significa "privado para todos los objetos de esta clase".

 class Rational(n: Int, d: Int)

es básicamente lo mismo que

 class Rational(private[this] val n: Int, private[this] val d: Int)

En un nivel más alto, casi filosófico, se podría decir que

 class Rational(n: Int, d: Int) { ... }

es como un método estático que devuelve un Rational y tiene parámetros n y d , y como en cualquier método, sus parámetros son locales para el método. Al calificar los parámetros con val o var , convierte esos parámetros en campos de Rational , sin tener que escribirlos dos veces: una vez como un parámetro para el método (o constructor, que es el nombre más específico para este método estático) y otra vez como un campo

about 4 years ago · Santiago Trujillo Relatório

0

Estaba leyendo el mismo libro y tenía la misma duda. Cuando descompilé el código, esto es lo que se generó.

 class Employee(var age: Int)

transpilado a

 public class Employee { private int age; public int age() { return this.age; } public void age_$eq(final int x$1) { this.age = x$1; } public Employee(final int age) { this.age = age; super(); } }

Próximo,

 class Employee(val age: Int)

transpilado a

 public class Employee { private final int age; public int age() { return this.age; } public Employee(final int age) { this.age = age; } }

Próximo,

 class Employee(age: Int)

transpilado a

 public class Employee { public Employee(final int age) { } }
  • Parece haber un Constructor de la clase Employee , con solo un parámetro llamado age . Eso muestra claramente que la edad no se adjunta a la instancia de Empleado. No hay ningún atributo de instancia denominado edad en Empleado.
  • Sin embargo, si añadimos un getter de edad simple, esto genera un atributo final privado para el mismo.

Ejemplo

 class Employee(age: Int) { def getAge(): Int = age }

transpilado a

 public class Employee { private final int age; public int getAge() { return this.age; } public Employee(final int age) { this.age = age; } }
about 4 years ago · Santiago Trujillo Relatório
Responde à pergunta
Encontrar trabalhos remotos

Descubra a nova forma de encontrar um emprego!

melhores empregos
Principais categorias de trabalho
Empresas
Postar vaga Preços Comercial
Jurídico
Termos e Condições Política de privacidade
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Recomende algumas ofertas para mim
Preciso de ajuda