Falando sobre as variáveis e constantes da gramática Kotlin (2)

https://my.oschina.net/u/3847608/blog/1837610 

Desta vez, falei sobre as variáveis ​​e constantes de Kotlin e apresentarei principalmente o seguinte:

  • 1. Definição básica de variáveis
  • 2. A diferença entre var e val
  • 3. Inferência de tipo inteligente
  • 4. Acessador de atributo personalizado
  • 5. Var é variável e val deve ser imutável?

1. Comparação de uso variável e constante em Kotlin e Java

  • 1. Defina uma variável e constante em Java
public String name = "Mikyou";//定义变量
public final int age = 18;//final定义常量
  • 2. Defina uma variável e constante em Kotlin
var name: String = "Mikyou"
val age: Int = 18

ou

var name = "Mikyou"
val age = 18

Resumo: a partir da comparação acima, podemos obter:

  • 1. Kotlin define uma variável e constante mais concisa e flexível que Java
  • 2. O Kotlin possui um mecanismo de inferência de tipo.Quando uma variável ou constante é inicializada, a declaração de tipo pode ser omitida, e será usada como o tipo da variável de acordo com o tipo do valor inicializado.
  • 3. Kotlin declara que variáveis ​​e constantes devem usar var (variável), val (constante) palavra-chave começa, depois nome e, finalmente, tipo (se houver um tipo de valor inicializado, ele pode ser omitido diretamente)
  • 4. Comparado com Java, o modificador de acesso padrão do Kotlin é público e Java é o padrão
  • 5. Java geralmente começa com o tipo e depois com o nome, e o tipo não pode ser omitido; esse tipo de operação não é possível no Kotlin. Como o tipo pode ser omitido em Kotlin, ou seja, o tipo é relativamente fraco, então Kotlin colocará o tipo no final, geralmente contendo o valor de inicialização omitirá a declaração de tipo subsequente.

Dois, o uso constante e variável de Kotlin

var name: String = "Mikyou"
var address: String?//如果这个变量没有初始化,那么需要显示声明类型并且指明类型是否可null
address = "NanJing"
val age: Int = 18

ou

var name = "Mikyou"
val age = 18
  • 1. Variáveis ​​e declarações de constantes devem começar com as palavras-chave "var" e "val".
  • 2. A estrutura de variáveis ​​e constantes: (var ou val) Nome: (Vírgula dividida) Tipo de variável = valor de inicialização.
  • 3. Conversão de tipo inteligente (o compilador avisa como elenco inteligente). Se a variável ou constante contém o valor inicial, o tipo pode ser omitido. O compilador irá analisar o tipo do valor inicializado como a variável e o tipo constante por padrão.
  • 4. Se a variável não for inicializada, o tipo declarado precisa ser exibido e se o tipo é anulável ou não precisa ser especificado.

Três, acessador de atributo personalizado de Kotlin

Os atributos são o recurso de primeira classe em Kotlin. Eles são usados ​​para substituir campos e métodos setter e getter em Java por um atributo. Os acessadores set e get em Kotlin são equivalentes aos métodos setter e getter em Java. Um novo recurso do Kotlin é que você pode definir acessores para propriedades em uma classe, incluindo acessores setter e getter. Esse recurso é muito adequado para um novo atributo que precisa ser calculado por meio da lógica de vários atributos. Então, a operação do processo de cálculo lógico não precisa abrir um método como o Java para conseguir. Você pode executar operações lógicas diretamente no acessador de atributo.

  • 1. Acessador de atributo personalizado

Implementado em Java:

public class Rectangle {

    private float width;
    private float height;

    public Rectangle(float width, float height) {
        this.width = width;
        this.height = height;
    }

    public boolean isSquare() {//在java中实现一个方法进行相关的逻辑计算
        return width == height;
    }

}

Implementado em Kotlin:

class Rectangle(width: Float, height: Float) {
    val isSquare: Boolean//在Kotlin中只需要一个属性就能解决,重新定义了isSquare的getter属性访问器,访问器中可以写入具体逻辑代码。
        get() {
            return width == height
        }
}
  • 2. Acessador de atributo de definição personalizada

Implemente um método setter em uma visualização customizada no Android em Java.

public class RoundImageView extends ImageView {
        ...
    
    public void setBorderColor(int color) {
        mColor = color;
        invalidate();
    }
        ...
}

Implemente o acessador de atributo definido em uma visualização personalizada no Android em Kotlin.

class RoundImageView @JvmOverloads constructor(context: Context, attributeSet: AttributeSet? = null, defAttrStyle: Int = 0)
    : ImageView(context, attributeSet, defAttrStyle) {

    var mBorderColor: Int
        set(value) {//自定义set属性访问器
            field = value
            invalidate()
        }
}

Quarto, a diferença entre var e val em Kotlin

  • 1, referência de variável var (da variável) . E o valor da variável modificada por ele pode ser alterado, com permissões de leitura e gravação, o que equivale a variáveis ​​não finais em Java.
  • 2. Val (do valor) é uma referência imutável . E o valor da variável modificada por ele geralmente é inicializado e não pode ser relançado no estágio posterior, caso contrário, ele lançará uma exceção de compilação ( esta frase será discutida, consulte a discussão sobre val imutável e legível em Kotlin ) , que são constantes modificadas finais equivalentes em Java.
  • 3. No processo de desenvolvimento do Kotlin, use a palavra-chave val para declarar todas as variáveis ​​do Kotlin o máximo possível. Use var apenas em alguns casos especiais. Todos nós sabemos que as funções no Kotlin são cidadãos de primeira classe e muito conteúdo de programação funcional O uso de variáveis ​​referenciadas imutáveis ​​o torna mais próximo do estilo de programação funcional.
  • 4. Deve-se notar que a referência val em si é imutável, mas o objeto para o qual ela aponta pode ser mutável ( para discussão e verificação deste problema, consulte a discussão sobre val imutável e legível em Kotlin ).
  • 5. A palavra-chave var permite alterar seu valor, mas seu tipo não pode ser alterado.

5. Discussão sobre imutabilidade e legibilidade de val em Kotlin

Uma vez que Kotlin é uma nova linguagem, frequentemente nos lembramos de alguns dos chamados teoremas no processo de aprendizagem e não nos aprofundamos realmente em por que esse é o caso. Por exemplo, pegando o tópico de hoje, acredito que muitas pessoas pensam (incluindo eu no início) que as variáveis ​​modificadas de var são mutáveis, enquanto as variáveis ​​modificadas de val são imutáveis. Então, depois de aprender o acessador de atributo personalizado de Kotlin, você sentirá que há um problema. Depois fui dar uma olhada em alguns blogs estrangeiros, embora existam descrições, depois de lê-las, o que me deixa ainda mais confuso é que o valor da variável modificada por val pode ser alterado e lido, e a referência subjacente também é alterada. A primeira frase é realmente compreensível, mas a última frase ainda é reservada. Então comecei a escrever autenticação de demonstração. Citando a frase original de um blog estrangeiro "Mas podemos dizer que val garante que a referência subjacente ao objeto é imutável? Não ..." endereço de origem do blog estrangeiro

  • 1. A suposição de que val é imutável e legível

Hipótese 1: A variável modificada por val em Kotlin não pode ser considerada imutável, somente pode-se dizer que a permissão da variável modificada por val é legível.

Hipótese 2: A referência à variável modificada por val em Koltin é imutável, mas o objeto apontado é variável.

  • 2. Argumento de que val é imutável e legível

Argumento Hipótese 1: Durante nosso desenvolvimento em Kotlin, as variáveis ​​modificadas com val não podem ser atribuídas novamente, caso contrário, uma exceção de tempo de compilação será lançada. Mas o fato de não poder ser atribuído novamente não significa que seja imutável. Porque Kotlin é diferente de Java no recurso de acessadores de atributos personalizados. Esse recurso parece contradizer a imutabilidade da variável modificada por val. Esse problema não existe em Java. Se variáveis ​​modificadas finais forem usadas, não há o chamado conceito de acessador personalizado.

fun main(args: Array<String>) {
    val name = "Hello Kotlin"
    name = "Hello Java"
}

erro de impressão:

Error:(8, 5) Kotlin: Val cannot be reassigned

Definir obter exemplo de acessador de atributo

class RandomNum {
    val num: Int
        get() = Random().nextInt()
}

fun main(args: Array<String>) {
    println("the num is ${RandomNum().num}")
}

resultado de impressão:

the num is -1411951962
the num is -1719429461

Resumo: O exemplo acima pode mostrar que a Hipótese Um é verdadeira. A variável modificada por val em Kotlin não pode ser considerada imutável, mas apenas tem permissões legíveis.

Hipótese 2 do argumento: a partir do argumento 1, sabemos que a variável modificada pelo val de Kotlin é mutável, então sua referência subjacente é mutável? Um blog estrangeiro diz que as citações variam, é verdade? Através de um exemplo para ilustrar.

Classe de usuário:

package com.mikyou.kotlin.valtest
open class User() {
    var name: String? = "test"
    var age: Int = 18
    var career: String? = "Student"
}

Aula do aluno:

class Student() : User()

Categoria de professor:

class Teacher() : User()

Interface do cliente:

interface Customer {
    val user: User//注意: 这里是个val修饰的User实例引用
}

Classe de implementação VipCustomer:

class VipCustomer : Customer {
    override val user: User
        get() {
//            return Student().apply {
//                name = "mikyou"
//                age = 18
//                career = "HighStudent"
//            }
            return Teacher().apply {
                //看到这里很多人肯定认为,底层引用也会发生改变,毕竟Student, Teacher是不同的对象了。但是事实是这样的吗?
                name = "youkmi"
                age = 28
                career = "HighTeacher"
            }
        }
}

teste:

fun main(args: Array<String>) = VipCustomer().user.run {
    println("my name is $name, I'm $age years old, my career is $career, my unique hash code is ${hashCode()} ")
}

resultado de impressão:

my name is mikyou, I'm 18 years old, my career is HighStudent, my unique hash code is 666988784 
	
//切换到Teacher
my name is youkmi, I'm 28 years old, my career is HighTeacher, my unique hash code is 666988784

Resumo: A partir do exemplo acima, pode-se mostrar que a hipótese dois é verdadeira Dois hashCodes de objeto diferentes indicam que o endereço de referência do usuário não foi alterado e o objeto para o qual a referência aponta pode ser alterado.

Este é o fim da gramática básica da entrada do Kotlin. O próximo artigo continuará a mergulhar no conteúdo relacionado ao Kotlin

Acho que você gosta

Origin blog.csdn.net/az44yao/article/details/112917698
Recomendado
Clasificación