Kotlin ne permet pas ceci:
private lateinit var port: BigInteger;
Que puis-je utiliser pour marquer un entier comme une valeur comme autoriser la fin de l'initialisation?
Je comprends pourquoi em> cela ne fonctionne pas (Int est primitif), j'ai besoin de savoir quoi utiliser à la place ?
Modifier 1
Ce n'est pas un doublon car je veux savoir quoi utiliser dans ce cas, pas pourquoi cela se produit: Pourquoi Kotlin ne permet-il pas d'utiliser lateinit avec des types primitifs?
Modifier 2 Comme suggéré par @Roland ci-dessous - BitInteger fonctionne pour moi:
private lateinit var port: Int;
Je l'utilise juste pour générer une URL, donc je n'en ai vraiment besoin que dans une concaténation de chaînes. p>
3 Réponses :
Je ne connais pas la solution parfaite que vous recherchez, mais je le fais comme ceci (au cas où vous seriez réellement obligé d'utiliser un type primitif):
class Example{
private var _port: Int? = null
var port:Int
get() = this._port!!
set(i) { _port = i }
}
Au moins ceci vous permet d'utiliser la propriété comme si elle n'était pas nullable. La meilleure solution que nous avons trouvée pour nous jusqu'à présent!
Voir ma modification, je l'ai en fait changé en BigInteger à la place, et cela fonctionne bien pour moi (je l'utilise pour générer une URL donc je la convertis simplement en chaîne). Peut-être pourrais-je utiliser BigInteger et le lancer si j'avais besoin de la valeur Int réelle.
@mikeb ouais j'ai vu ça, mais je pense que dans certains cas, vous ne pouvez pas faire une telle solution de contournement
Certaines variantes me viennent à l'esprit, mais selon la manière dont vous l'utiliserez plus tard, aucune ne vous conviendra peut-être.
utilisez simplement une valeur par défaut, par exemple:
url = "$host${port?.let { ":$it" }?:""}"
// or:
url = port?.let { "$host:$it" } ?: host
// or
url = listOfNotNull(host, port).joinToString(":")
utilisez un autre type de Number au lieu de Int , par exemple
class Server {
var port : Int? by Delegates.vetoable(null as Int?) {
_, _, newValue -> newValue != null
}
}
Vous pouvez ensuite appeler port.toInt () si vous en avez besoin. Mais: il y a beaucoup de types de Number , donc réduisez-le à par exemple BigInteger peut avoir du sens. Sinon, vous risquez d'obtenir des objets que vous ne souhaitez pas accepter en premier lieu.
en utilisant Delegates.notNull
class Server {
var port : Int? = null
}
mais: même si vous épargnez votre valeur null , vous ne pouvez pas vérifier si la variable a été initialisée, il vous suffit donc de gérer une exception dès que vous souhaitez accéder ça ... pas très gentil je pense ... mais si vous êtes sûr d'avoir une valeur, alors cela pourrait vous convenir aussi.
utilisez simplement Int? et ignorez le lateinit , par exemple:
var port : Int by Delegates.notNull()
Au lieu de :: port.isInitialized , vous demanderiez port! = null , mais: vous devez gérer le possible null - valeur maintenant, mais avec ? cela ne devrait pas être un si gros problème.
utilisez Int? avec Delegates.vetoable au cas où vous ne voudriez pas accepter les valeurs null après avoir obtenu votre première value, ce qui en fait quelque chose comme lateinit ;-)
class Server {
lateinit var port : Number
}
et vérifiez à nouveau en utilisant port! = null , qui se comporte désormais comme ::port.isInitialized
Non pas que je sois un grand fan des deux derniers car ils introduisent à nouveau null , mais en fonction de ce que vous faites, cela pourrait être parfaitement ok ...
Comme vous avez ajouté quelque chose concernant la concaténation String , j'utiliserais encore plus Int? ici. Vous pouvez alors toujours utiliser quelque chose comme:
var port : Int = 8080
La même chose ne peut pas être vraiment plus facile avec le :: port.isInitialized ?
Si votre projet n'est pas multiplateforme, la solution évidente serait
@Suppress("PLATFORM_CLASS_MAPPED_TO_KOTLIN") lateinit var i: java.lang.Integer
qui a une correspondance biunivoque avec les valeurs Int (contrairement à BigInteger ).
Hm, quelle limitation apparemment arbitraire. Comme si
Int?était interdit.Vous ne pouvez pas entrer tardivement les types nullables, donc
Int?ne fonctionne pas.Copie possible de Pourquoi Kotlin n'autorise pas l'utilisation de lateinit avec des types primitifs?
@marstran - Pas un doublon, j'ai dit spécifiquement que je comprends pourquoi cela ne fonctionne pas, et cette question y répond bien. Je veux savoir quoi faire à la place .
Vous ne pouvez pas utiliser
lateinit, vous devez donc l'initialiser.vous pouvez l'envelopper, si vous voulez vraiment garder
Intet ne voulez pas de valeur par défaut ... ou utiliser un autre type, par exempleBigInteger? ;-)si vous faites une concaténation
String, je préférerais probablement m'en tenir àInt?à la place ... ou peut-être mêmelateinit Stringet vérifier l'entrée à la place ...