How to use ternary operator with System::Boolean? This sample code always returns true:
bool Test(Boolean^ value)
{
return value ? true : false;
}
Your usage of System::Boolean is wrong in the first place and it has nothing to do with ternary operator. Never pass a value types as reference.
Regadless of unnecessary penalities, the code in your answer will work but not in C#. The compiler will complain when you want to call bool Test(Boolean^ value) function. Because there is no concept of referenced value type in C#.
Answering my own premature question, this code works:
bool Test(Boolean^ value)
{
return (bool)value ? true : false;
}
EDIT: better yet (and following Hans' and Matt's advice) this code works better:
bool Test(Boolean value)
{
return value ? true : false;
}
Or, because Boolean and bool are convertible this is also good code, which relies on automatic conversion that happens elsewhere. Example has very little sense except for showing the ternary operator:
bool Test(bool value)
{
return value ? true : false;
}
Related
Is there a neat functional way of carrying out this return without first assigning the value to the variable?
Note: The first get is guaranteed of returning a valuable from the map and hence the "!!".
The second get is not guaranteed and can thus return null.
Thank you
fun isHidden(digitsChosen: String, digitNext: Char): Boolean {
val middlePosition = positionsHidden.get(digitsChosen.last())!!.get(digitNext)
return middlePosition != null && digitsChosen.dropLast(1).contains(middlePosition).not()
}
Well, you can use something like this:
fun isHidden(digitsChosen: String, digitNext: Char): Boolean {
return positionsHidden.get(digitsChosen.last())?.let {
it.get(digitNext)?.let {
digitsChosen.dropLast(1).contains(it).not()
} ?: false
} ?: false
}
Which seems to be a little bit NPE-proof, but more clumsy.
Anyway, I would recommend you to replace !!.get with ?.get and deal with null explicitly.
Recently I've been delving into Flutter's ecosystem and Dart has proven itself a neat and simple language.
Currently, I am looking for a best practice to run methods if an optional variable is not null.
In other words, I am looking for something in Dart that is like Kotlin's let operator :
variable?.let {
doStuff();
doABitMoreStuff();
logStuff();
}
Anyone got any ideas or best practices around this?
I've looked into Dart's documentation and have found nothing that would fit my requirements.
King regards,
With the new Dart extension functions, we can define:
extension ObjectExt<T> on T {
R let<R>(R Function(T that) op) => op(this);
}
This will allow to write x.let(f) instead of f(x).
Dart's equivalent would be a null-aware cascade operator:
The Dart approach would be a to use a null-aware cascade:
SomeType? variable = ...
variable
?..doStuff()
..doABitMoreStuff()
..logStuff();
The null-aware cascade works like the normal cascade, except that if the receiver value is null, it does nothing.
You could make your own using a static function though:
typedef T LetCallback<T>(T value);
T let<T>(T value, LetCallback<T> cb) {
if (value != null) {
return cb(value);
}
}
Then used like that:
let<MyClass>(foo, (it) {
})
We can do it with Dart 2.6 or later.
extension ScopeFunctionsForObject<T extends Object> on T {
ReturnType let<ReturnType>(ReturnType operation_for(T self)) {
return operation_for(this);
}
}
usage: https://github.com/YusukeIwaki/dart-kotlin_flavor#let
The difference between x?.let{ } and if (x != null) { } in Kotlin is that the former promotes x to be non-nullable. Since Kotlin has non-nullable types, it prevents you from needing to write x!! to assert the non-nullability inside the block.
Dart doesn't have non-nullable types (yet), so that distinction isn't important in Dart.
Just use if (x != null) { ... }.
If Dart gets non-nullable types, you can be assured that the null check in the condition will also promote x to non-nullable inside the block (if x is a local variable, is not mutated inside the block, other restrictions may apply).
(EDIT: Dart now has nullable types, and x != null promotes x to non-null.)
From your other comments, it sounds like you might be wanting the Kotlin behavior of x?.run { ... } instead, which binds this to x inside the lambda block. There is no corresponding feature in Dart. You cannot override this, it's always bound to the the object that the current method was called on, even inside nested closures which captures the value of this just as they capture other variables.
Using this extension:
extension Ext on Object? {
void ifNotNull(Function() action) {
if(this != null){
action();
}
}
}
You can achieve something similar:
object.ifNotNull(() => {
// safe code
});
I guess a closure does what you want
class Foo {
var x = 42;
void bar() {
() {
print(x);
doStuff();
doABitMoreStuff();
logStuff();
}();
}
}
Even though Dart doesn't have the let like behavior as of Kotlin but we can certainly emulate it with concise and readable code. Maybe something like this:
void main() {
String str = null;
str?.isEmpty ?? Function.apply(() {
print("Hey there you cheeky null valued variable");
}, []);
}
i implemented let function with extension function like this:
extension KotlinLet on Object?{
void let(Function callback ){
if (this != null) {
callback();
}
}
Object? also(){
if (this != null) {
return this;
}
}
}
You can simply use this package kotlin_flavor: https://pub.dev/packages/kotlin_flavor/install
There is no direct equivalent, because there is no need for it in Dart. Dart is a lot more like Java and you often end up with similar solutions.
There is almost no syntactic sugar in Dart. It's supposed to be easy to learn.
Also, Dart does not enforce strict null checks, all variables are nullable, and the language is single-threaded. That's why there is no need for let. Use if instead:
if(variable != null) {
doStuff();
doABitMoreStuff();
logStuff();
}
Ideally, I think the commented-out if statements make more sense, at least to me. I mean, if someone asks me if null is bigger than 0, than I would answer no. Or if null is true, then also no. But those did not work as I expected, and throw compilation errors. So, I have changed those like below. But those do not look good or concise. Is there a better way to handle these?
class Result(val code:Int)
{
}
fun getResult():Result?
{
return null;
}
fun main(args: Array<String>)
{
var result = getResult();
var success:Boolean? = null;
//if(result?.code > 0)
if(result?.code?:0 > 0)
{
print("Good.");
}
//if(success)
if(success == true)
{
print("Good.");
}
}
The > is compiled to a call of compareTo(other: Int), which works by convention (its defined as an operator on Int). You cannot invoke this function on nullable Int? though.
There'd be a workaround: Create another extension on Int?:
operator fun Int?.compareTo(other: Int): Int =
(this ?: 0).compareTo(other)
Now your call does work:
if (result?.code > 0)
print("Good.")
the nullable element is actually the Result instance itself, not its code property.
i think using let in combination with the safe-get operator on the result more accurately reflects the design of the code:
result?.let {
if(it.code > 0) {
}
}
The reason the commented-out code did not compile is because result?.code is nullable and you can't call comparing operator (i.e > in this case) on a nullable expression because they don't type match. (it is defined to only accept non-nullable types)
if null is bigger than 0, than I would answer no. Or if null is true, then also no
Kotlin completely disambiguates between nullable and non-nullable entity. So, at compile time kotlin compiler refuses to compile if you are comparing something with a nullable type, to avoid run time exception ahead of time. In java,
Integer x = null;
System.out.println(x > `)
this compiles but throws a NullPointerException on runtime, which you obviously do not want. Kotlin compiler is just being smart here to avoid such runtime exceptions by refusing to compile.
Now onto the better way to deal with it, like everyone said, using let is an appropriate way. A simpler way can be a regular null check with if expresion
if(result != null && result.code > 0) {
print("Good.");
}
result?.code > 0
It's not working because > internally calls compareTo() method. compareTo() method does not work on a nullable object. That's why you have to add elvis operator(?:) on variable code to assign a value if the code variable is null. So that the value is not null and then compareTo() method works.
result?.code?:0 > 0
I have added a let to solve. If the result is not null then we will execute the code within the let block. Please check the updated code.
class Result(val code:Int){
}
fun getResult():Result?{
return null;
}
fun main(args: Array<String>){
var result = getResult();
var success:Boolean? = null;
//if(result?.code > 0)
if(result?.code?:0 > 0){
print("Good.");
}
// Updated Code
result?.let{
if(result.code > 0)
print("Good.")
}
//if(success)
if(success == true){
print("Good.");
}
}
I am porting my template code to XTend. At some point I have this type of condition handling in a test case:
#Test
def xtendIfTest() {
val obj = new FD
if (true && obj?.property?.isNotNull) {
return
}
fail("Not passed")
}
def boolean isNotNull(Object o) {
return o != null
}
class FD {
#Accessors
String property
}
This works as expected as the property is null and the test will fail with "Not passed" message. But a simple change in the return type of isNotNull method to Boolean (wrapper):
def Boolean isNotNull(Object o) {
return o != null
}
fails with a NullPointerException. Examining the generated java code for this I can see that XTend is using an intermediate Boolean object expression and that is the cause of NPE. Am I missing the point of the XTend null safe operator (?.) or I can't use a method like this after the operator?
Thanks.
The operator behaves properly. The exception is thrown because of the usage of a Boolean in an if-expression, which requires auto-unboxing.
If you try the following:
#Test
def xtendIfTest() {
val Boolean obj = null
if (obj) {
return
}
fail("Not passed")
}
You will also run into a NullPointerException.
This is consistent with the Java Language Specification (https://docs.oracle.com/javase/specs/jls/se7/html/jls-5.html#jls-5.1.8) - when auto-unboxing is required this can yield a NullPointerException:
#Test
public void test() {
Boolean value = null;
if (value) { // warning: Null pointer access: This expression of type Boolean is null but requires auto-unboxing
// dead code
}
}
Hope that helps.
Short answer: Change the second null-safe call to a regular call.
I.e. change
obj?.property?.isNotNull
to this:
obj?.property.isNotNull
Long answer:
The docs describe the null-safe operator thusly:
In many situations it is ok for an expression to return null if a
receiver was null
That means the second call in your example, property?. won't even call isNotNull if the left side of the call was null. Instead, it will return null. So the conditional "effectively" evaluates to:
if (true && null) { // causes NPE when java tries to unbox the Boolean
(By the way - the true is superfluous in this context, but I'm keeping it just in case you had another condition to check - I'm assuming you're just simplifying it to true for this example.)
If you make the change I'm suggesting, obj?.property will be evaluated, then the result will be passed to isNotNull, evaluating to this:
if (true && isNotNull(null)) {
which returns the proper Boolean object that will be auto-unboxed as expected.
A Word of Caution
In your first form of isNotNull, i.e. the one returning primitive boolean, you should actually get a warning like "Null-safe call of primitive-valued feature isNotNull, default value false will be used".
This is because you're stretching the intent of the null-safe call, which is to return null without invoking the right side method if the left side of the operator was null. But if your isNotNull returns a primitive boolean, the whole expression obviously can't evaluate to null, so Xtend uses a default instead, which is false for booleans.
To emphasize the problem in a different way - it evaluates to false without calling isNotNull - that means even if you used a method isNull after the operator, it would still return false!
The docs also mention this behavior (albeit in general terms):
For primitive types the default value is returned (e.g. 0 for int).
This may not be what you want in some cases, so a warning will be
raised by default
So I recommend always using a non-primitive return value on the right-hand side of a null-safe call. But if you're going to convert the isNotNull to a regular call as I suggested, this rule doesn't apply, and either return type is fine.
I have the following code, which I thought would work:
property Nullable<double> Angle {
Nullable<double> get() {
return nullptr;
}
}
It doesn't. How can I do it? Does c++/CLI even support nullable types?
OK, found it, after a lot of hassle:
to return null, just do
return Nullable<double>();
to return non-null:
return Nullable<double>(12321);
It is important to declare the return value as Nullable<double> and not Nullable<double>^, as if you do it, when using other languages as C# and vb.net, you'll see the type as ValueType instead of double?.