AskOverflow.Dev

AskOverflow.Dev Logo AskOverflow.Dev Logo

AskOverflow.Dev Navigation

  • Início
  • system&network
  • Ubuntu
  • Unix
  • DBA
  • Computer
  • Coding
  • LangChain

Mobile menu

Close
  • Início
  • system&network
    • Recentes
    • Highest score
    • tags
  • Ubuntu
    • Recentes
    • Highest score
    • tags
  • Unix
    • Recentes
    • tags
  • DBA
    • Recentes
    • tags
  • Computer
    • Recentes
    • tags
  • Coding
    • Recentes
    • tags
Início / coding / Perguntas / 79262237
Accepted
user24723440
user24723440
Asked: 2024-12-08 18:20:13 +0800 CST2024-12-08 18:20:13 +0800 CST 2024-12-08 18:20:13 +0800 CST

Correspondência definitiva em correspondência de padrões Java

  • 772

Tenho algumas dúvidas sobre certas partes da correspondência definitiva na especificação da linguagem Java.

Por exemplo, em 6.3.1.1:

Operador condicional-and && As seguintes regras se aplicam a uma expressão condicional-and a && b(§15.23):

• Uma variável de padrão introduzida por aquando true é definitivamente correspondida em b.

• Uma variável de padrão é introduzida por a && bquando verdadeiro se (i) for introduzida por aquando verdadeiro ou (ii) for introduzida por b quando verdadeiro.

Deve-se notar que não há regra para introduzir uma variável de padrão por a && bquando false. Isso ocorre porque não é possível determinar em tempo de compilação qual operando será avaliado como false .

Não entendo por que o motivo para "não há regra para introduzir uma variável de padrão por a && b quando falso" é "não é possível determinar em tempo de compilação qual operando será avaliado como falso".

Se houver

a instanceof String s

então a variável padrão   s  é introduzida por esta expressão somente quando o valor desta expressão é   true  . Então podemos dizer "a variável padrão sé introduzida pela expressão a instanceof String squando true".

Seja " quando verdadeiro " ou " quando falso ", ambos parecem ser apenas escritos gerados pela previsão do valor de uma expressão. (Ou melhor, eles levam o valor da expressão em consideração.)

Acho que isso é completamente diferente de " quando verdadeiro " ou " quando falso " que aparecem na atribuição definida .

Por exemplo:

{
 int k;
 int n = 5;
 if (n > 2)
 k = 3;
 System.out.println(k); /* k is not "definitely assigned"
 before this statement */
}

16.2.7:

As seguintes regras se aplicam a uma declaração if (e) S:

• Vé [des]atribuído após if (e) Sse e somente se V é [des]atribuído após Se V é [des]atribuído após e quando falso .

Acho que se " quando falso " aqui for o mesmo que em correspondência definida , então kserá definitivamente atribuído aqui.

Então, acho que a atribuição definida não leva em conta o valor de uma expressão ( exceto para algumas expressões com constantes de tempo de compilação ), (assim como a especificação declara), (assim como neste exemplo), mas a correspondência definida obviamente considera o valor da expressão (assim como no exemplo anterior).

Nesse caso, acho que devo conseguir adicionar o seguinte depois da versão 6.3.1.1:

Uma variável de padrão é introduzida por a && bquando falso se (i) for introduzida por aquando falso ou (ii) for introduzida por a quando verdadeiro ou (iii) for introduzida por bquando averdadeiro.

Acho que não há nada de errado nisso, porque estou apenas considerando os valores dessas expressões e anotando as situações previstas. Isso não tem nada a ver com os valores em tempo de compilação.

No entanto, a nota de rodapé é completamente diferente da minha visão e contém motivos que não entendo de forma alguma.

Então estou aqui para pedir ajuda. Obrigado por ler e responder.

java
  • 2 2 respostas
  • 77 Views

2 respostas

  • Voted
  1. Best Answer
    Sweeper
    2024-12-08T21:06:37+08:002024-12-08T21:06:37+08:00

    Se uma variável de padrão é introduzida é muito diferente de atribuição definida. A parte que você citou de 16.2.7 é sobre instruções if, não sobre &&.

    Intuitivamente, não há regra para "uma variável de padrão é introduzida por a && bquando false" porque não podemos saber em tempo de compilação qual padrão é correspondido. Considere:

    void f(Object o) {
        if (o instanceof String s && o instanceof Integer i) {
            
        } else {
    
        }
    }
    

    Qual variável de padrão deve ser definitivamente correspondida no elsebranch? Nenhuma variável de padrão deve ser introduzida aqui, porque if elseé executado, isso significa que onão é uma string e um inteiro. Pode ser uma string, pode ser um inteiro, pode ser qualquer outra coisa. Não obtivemos nenhuma informação útil sobre oin the elsebranch.

    Vamos dar uma olhada na seção 6.3.2.2 da especificação. Variáveis ​​de padrão introduzidas por o instanceof String s && o instanceof Integer iwhen false serão definitivamente atribuídas no elsebranch. E de acordo com sua adição proposta à especificação, sé uma variável de padrão introduzida por o instanceof String s && o instanceof Integer iwhen false, porque sé uma variável de padrão introduzida por o instanceof String swhen true, então a condição (ii) se aplica. Isso é obviamente incorreto porque o elseainda pode ser executado if onão é um String.

    O mesmo se aplica a qualquer outro par de padrões de tipos que você queira combinar.

    Na verdade, a condição (iii) em sua proposta também não está bem definida. "introduzido por b quando a é verdadeiro" não está definido. Existem apenas 3 formas conforme listadas na parte logo antes do cabeçalho da seção de 6.3.1 :

    • introduzido por alguma expressão quando verdadeiro
    • introduzido por alguma expressão quando falso
    • introduzido por alguma declaração

    Você poderia dizer algo assim:

    Uma variável de padrão Vé introduzida por a && bquando falso, se e somente se Vé introduzida por aquando falso e V é introduzida por bquando falso.

    que reflete esta regra para &&atribuição definitiva ( 16.1.2 ):

    V é [des]atribuído após a && b quando falso se e somente se V é [des]atribuído após a quando falso e V é [des]atribuído após b quando falso.

    No entanto, isso é discutível, porque a mesma variável de padrão não pode ser introduzida por duas expressões diferentes. Mas se pudesse, seria um caso como este:

    // imagine if this works
    if (!(o instanceof String v) && !(o instanceof Integer v)) {
    
    } else {
        // 'v' could be introduced here, though its type would be something like Either<String, Integer>
        // Java's type system doesn't have that yet.
    }
    
    • 4
  2. 许家宝
    2024-12-08T19:32:45+08:002024-12-08T19:32:45+08:00

    A variável pattern foi introduzida no Java 16.

    por exemplo:

    if (obj instanceof Type var) {
    // The variable 'var' is bound to 'obj' if it is an instance of 'Type'
    }
    

    a linha " não há regra para introduzir uma variável de padrão por a && b quando falso "

    considere o exemplo abaixo:

    if ((a instanceof String s) && (b instanceof String s)) {
    }
    

    isso causará um conflito em tempo de compilação, porque

    1. Se a e b forem instâncias de String, então s seria introduzido duas vezes, o que é ilegal porque leva à ambiguidade no código.
    2. Se a expressão inteira for avaliada como falsa, a variável de padrão s não poderá ser introduzida em a e b ao mesmo tempo porque o compilador não sabe qual lado é responsável pela avaliação falsa.
    • 0

relate perguntas

  • Lock Condition.notify está lançando java.lang.IllegalMonitorStateException

  • Resposta de microsserviço Muitos para Um não aparece no carteiro

  • Validação personalizada do SpringBoot Bean

  • Os soquetes Java são FIFO?

  • Por que não é possível / desencorajado definir um lado do servidor de tempo limite de solicitação?

Sidebar

Stats

  • Perguntas 205573
  • respostas 270741
  • best respostas 135370
  • utilizador 68524
  • Highest score
  • respostas
  • Marko Smith

    Vue 3: Erro na criação "Identificador esperado, mas encontrado 'import'" [duplicado]

    • 1 respostas
  • Marko Smith

    Por que esse código Java simples e pequeno roda 30x mais rápido em todas as JVMs Graal, mas não em nenhuma JVM Oracle?

    • 1 respostas
  • Marko Smith

    Qual é o propósito de `enum class` com um tipo subjacente especificado, mas sem enumeradores?

    • 1 respostas
  • Marko Smith

    Como faço para corrigir um erro MODULE_NOT_FOUND para um módulo que não importei manualmente?

    • 6 respostas
  • Marko Smith

    `(expression, lvalue) = rvalue` é uma atribuição válida em C ou C++? Por que alguns compiladores aceitam/rejeitam isso?

    • 3 respostas
  • Marko Smith

    Quando devo usar um std::inplace_vector em vez de um std::vector?

    • 3 respostas
  • Marko Smith

    Um programa vazio que não faz nada em C++ precisa de um heap de 204 KB, mas não em C

    • 1 respostas
  • Marko Smith

    PowerBI atualmente quebrado com BigQuery: problema de driver Simba com atualização do Windows

    • 2 respostas
  • Marko Smith

    AdMob: MobileAds.initialize() - "java.lang.Integer não pode ser convertido em java.lang.String" para alguns dispositivos

    • 1 respostas
  • Marko Smith

    Estou tentando fazer o jogo pacman usando apenas o módulo Turtle Random e Math

    • 1 respostas
  • Martin Hope
    Aleksandr Dubinsky Por que a correspondência de padrões com o switch no InetAddress falha com 'não cobre todos os valores de entrada possíveis'? 2024-12-23 06:56:21 +0800 CST
  • Martin Hope
    Phillip Borge Por que esse código Java simples e pequeno roda 30x mais rápido em todas as JVMs Graal, mas não em nenhuma JVM Oracle? 2024-12-12 20:46:46 +0800 CST
  • Martin Hope
    Oodini Qual é o propósito de `enum class` com um tipo subjacente especificado, mas sem enumeradores? 2024-12-12 06:27:11 +0800 CST
  • Martin Hope
    sleeptightAnsiC `(expression, lvalue) = rvalue` é uma atribuição válida em C ou C++? Por que alguns compiladores aceitam/rejeitam isso? 2024-11-09 07:18:53 +0800 CST
  • Martin Hope
    The Mad Gamer Quando devo usar um std::inplace_vector em vez de um std::vector? 2024-10-29 23:01:00 +0800 CST
  • Martin Hope
    Chad Feller O ponto e vírgula agora é opcional em condicionais bash com [[ .. ]] na versão 5.2? 2024-10-21 05:50:33 +0800 CST
  • Martin Hope
    Wrench Por que um traço duplo (--) faz com que esta cláusula MariaDB seja avaliada como verdadeira? 2024-05-05 13:37:20 +0800 CST
  • Martin Hope
    Waket Zheng Por que `dict(id=1, **{'id': 2})` às vezes gera `KeyError: 'id'` em vez de um TypeError? 2024-05-04 14:19:19 +0800 CST
  • Martin Hope
    user924 AdMob: MobileAds.initialize() - "java.lang.Integer não pode ser convertido em java.lang.String" para alguns dispositivos 2024-03-20 03:12:31 +0800 CST
  • Martin Hope
    MarkB Por que o GCC gera código que executa condicionalmente uma implementação SIMD? 2024-02-17 06:17:14 +0800 CST

Hot tag

python javascript c++ c# java typescript sql reactjs html

Explore

  • Início
  • Perguntas
    • Recentes
    • Highest score
  • tag
  • help

Footer

AskOverflow.Dev

About Us

  • About Us
  • Contact Us

Legal Stuff

  • Privacy Policy

Language

  • Pt
  • Server
  • Unix

© 2023 AskOverflow.DEV All Rights Reserve