Muitas línguas gosto C++
, C#
e Java
permitem que você crie objetos que representam tipos simples, como integer
ou float
. Usando uma interface de classe, você pode substituir os operadores e executar lógica como verificar se um valor excede uma regra de negócios de 100.
Gostaria de saber se em alguns idiomas é possível definir essas regras como anotações ou atributos de uma variável / propriedade.
Por exemplo, C#
você pode escrever:
[Range(0,100)]
public int Price { get; set; }
Ou talvez C++
você possa escrever:
int(0,100) x = 0;
Eu nunca vi algo assim ser feito, mas, considerando o quão dependentes nos tornamos da validação de dados antes do armazenamento. É estranho que esse recurso não tenha sido adicionado aos idiomas.
Você pode dar exemplos de idiomas onde isso é possível?
java
c#
c++
annotations
attributes
Reactgular
fonte
fonte
data Bool = True | False
e para o que você deseja que você poderia dizerdata Cents = 0 | 1 | 2 | ...
ter um olhada em "tipos algébrica de dados" (que deve ser mais propriamente chamados tipos Hindley-Milner, mas as pessoas confundem isso com a inferência de tipos irritantemente) en.wikipedia.org/wiki/Algebraic_data_typetype
Afinal, existe uma palavra - chave em Pascal. A orientação a objetos é mais um padrão de design do que uma propriedade "atomar" das linguagens de programação.Respostas:
Pascal tinha tipos de subintervalos, ou seja, diminuindo o número de números que se encaixam em uma variável.
Ada também tem uma noção de intervalos: http://en.wikibooks.org/wiki/Ada_Programming/Types/range
Da Wikipedia ....
também pode fazer
E aqui é onde fica legal
C não possui um tipo estrito de subintervalo, mas existem maneiras de imitar um (pelo menos limitado) usando campos de bits para minimizar o número de bits usados.
struct {int a : 10;} my_subrange_var;}
. Isso pode funcionar como um limite superior para o conteúdo variável (em geral, eu diria: não use campos de bits para isso , isso é apenas para provar um ponto).Muitas soluções para tipos inteiros de comprimento arbitrário em outras linguagens acontecem no nível da biblioteca, ou seja, o C ++ permite soluções baseadas em modelo.
Existem idiomas que permitem monitorar estados variáveis e conectar asserções a ele. Por exemplo, em Clojurescript
A função
mytest
é chamada quandoa
mudou (viareset!
ouswap!
) verifica se as condições são atendidas. Este poderia ser um exemplo para implementar o comportamento de subintervalos em idiomas de ligação tardia (consulte http://blog.fogus.me/2011/09/23/clojurescript-watchers-and-validators/ ).fonte
for y in Year_Type loop ...
eliminando problemas como estouros de buffer.O Ada também é uma linguagem que permite limites para tipos simples; de fato, no Ada, é uma boa prática definir seus próprios tipos para o seu programa para garantir a correção.
Foi usado por um longo tempo pelo Departamento de Defesa, talvez ainda seja, mas eu perdi a noção do seu uso atual.
fonte
Consulte Limitando o intervalo de tipos de valor em C ++ para obter exemplos de como criar um tipo de valor verificado no intervalo em C ++.
Resumo executivo: Use um modelo para criar um tipo de valor com valores mínimo e máximo integrados, que você pode usar assim:
Você nem precisa de um modelo aqui; você pode usar uma classe para um efeito semelhante. O uso de um modelo permite especificar o tipo subjacente. Além disso, é importante observar que o tipo de
percent
acima não será umfloat
, mas uma instância do modelo. Isso pode não satisfazer o aspecto "tipos simples" da sua pergunta.Tipos simples são exatamente isso - simples. Eles geralmente são mais usados como os blocos de construção para criar as ferramentas necessárias em vez de serem usadas diretamente.
fonte
De acordo com o meu conhecimento, alguma forma restrita de sua intenção é possível em Java e C # através de uma combinação de anotações e padrão de proxy dinâmico (existem implementações internas para proxies dinâmicos em Java e C #).
Versão Java
A anotação:
A classe Wrapper que cria a instância do Proxy:
O InvocationHandler servindo como desvio a cada chamada de método:
A interface de exemplo para uso:
Método principal:
Resultado:
Versão C #
A anotação (em C # chamada atributo):
A subclasse DynamicObject:
A ExampleClass:
Uso:
Em conclusão, você vê que pode conseguir que algo assim funcione em Java , mas não é totalmente conveniente, porque
Os recursos da classe DynamicObject em C # removem a restrição de interface, como você vê na implementação de C #. Infelizmente, esse comportamento dinâmico remove a segurança do tipo estático nesse caso, portanto, são necessárias verificações de tempo de execução para determinar se uma chamada de método no proxy dinâmico é permitida.
Se essas restrições são aceitáveis para você, isso pode servir de base para novas escavações!
fonte
public virtual int Min { get; private set; }
é um truque agradável que iria encurtar o código significativamenteAs faixas são um caso especial de invariantes. Da Wikipedia:
Um intervalo
[a, b]
pode ser declarado como uma variável x do tipoInteger
com os invariantes x> = a e x <= b .Portanto, os tipos de subintervalo Ada ou Pascal não são estritamente necessários. Eles podem ser implementados com um tipo inteiro com invariantes.
fonte
Recursos especiais para tipos de alcance limitado não são necessários no C ++ e em outros idiomas com sistemas de tipos avançados.
No C ++, seus objetivos podem ser alcançados de maneira relativamente simples com tipos definidos pelo usuário . E em aplicações em que tipos de alcance limitado são desejáveis, dificilmente são suficientes . Por exemplo, também se deseja que o compilador verifique se os cálculos das unidades físicas foram escritos corretamente, para que a velocidade / tempo produza uma aceleração e a raiz quadrada da aceleração / tempo produza uma velocidade. Fazer isso convenientemente requer a capacidade de definir um sistema de tipos, sem nomear explicitamente todos os tipos que possam aparecer em uma fórmula. Isso pode ser feito em C ++ .
fonte