In my code I found situation where my method could return null. In this case I'd rather throw exception than return null.
However I don't want to use regular if because in my opinion it look terrible. See code:
class Type{}
#Field Queue<Type> q1 = [] as Queue
#Field Queue<Type> q2 = [] as Queue
Type regularMethod(){
Type toReturn = q1.poll() ?: q2.poll()
if(toReturn == null)
throw new RuntimeException("was null value")
return toReturn
}
Type myMethod(){
return q1.poll() ?: q2.poll() ?: exception()
}
Type exception(){
throw new RuntimeException("was null value")
}
What do you think about using elvis operator here?
Is it more readable for you?
Or can anyone suggest better solution?
It is of course a matter of preference and style, but I do not like it. The goal isn't to get to the fewest lines of code or the shortest lines of code. The goal should be to end up with concise expressive code. That often happens to be brief, but brevity isn't the primary goal. I think q1.poll() ?: q2.poll() ?: exception() isn't especially easy for the humans to parse.
I agree with Jeff, it's a bit hard to read and understand the code. My reasoning is that it hides what's really happening. You can of course make it more clear by improving the method name (to something like throwNewRuntimeException) and perhaps even take the message as a parameter. But I still don't like it. It feels unnecessary to add a new method for this.
I would either have written it exactly as your regularMethod or perhaps turned it around like this:
Type alternativeMethod() {
if (q1.empty && q2.empty)
throw new RuntimeException('Both queues are empty')
return q1.poll() ?: q2.poll()
}
In this version, I think the meaning is clear and easy to understand. As a bonus you've gotten rid of the clutter that seems to bother you. Even the error message is more descriptive.
What about guava preconditions? they are java so they are suitable for groovy too.
Preconditions.checkArgument((q1 && q2, "was null value")
Or using static import
checkNotNull(q1 && q2, "was null value")
Consider:
q1.poll() ?: q2.poll() ?: {throw new RuntimeException('Both empty')}()
Advantages:
No special idiom function where reader has to know what exception() really means.
No shared lib function that folks have to know about.
Just clear code using language primitives using lazy evaluation.
Values before error case, reads sanely from left to right.
Related
I am a beginner in kotlin and this is the code I tried to execute, but runtime error is being displayed. Please help me resolve this.
import java.util.*
fun main(args: Array<String>)
{
var inp = Scanner(System.`in`);
var t:Int = inp.nextInt();
repeat(t)
{
var n:Int = inp.nextInt();
var s:String = readLine()!!
for (i in s)
{
println(i);
}
println()
}
}
Exception in thread "main" kotlin.KotlinNullPointerException
at ProgKt.main(prog.kt:10) This is the error that is displayed.
Smeki's answer is right, but I just need to point something out since you're a beginner and it might get confusing.
Normally you'd do something like this:
val s = readLine()
Notice you're not specifying the type of s - it's being inferred by whatever you're assigning to it. Because readLine returns a nullable String?, which is a String that could be null (which is what the ? on the end means), then the compiler knows that s is a String?. It's the equivalent of doing this:
val s: String? = readLine()
And you can do that explicitly if you want! You usually don't need to though. And now you have your nullable s, you can do some null-checking to use it safely:
if (s != null) {
// we know it's not null, so now you can do stuff with it
} else {
// if you like, you can handle the null case separately, like breaking out of
// the loop (since null from readLine() means you've reached the end)
}
There's other ways to handle nulls and do null-checking - here's the documentation about it and I'd strongly recommend reading it and getting your head around it - it's a key part of the language! And it makes your life easier and code safer in the long run (avoids problems like this! !! gets around null-safety and it's usually a bad sign)
But remember when I said you can explicitly declare the type for s? Here's what I said it would be, and what you've written:
// correct
val s: String? = readLine()
// something's different!
val s: String = readLine()
See how you're missing the ? that says its a nullable type? Even if you're planning to null-check s after this, it's going to crash at this line because s is declared as a non-null type, and readLine() is gonna to be null at some point. When you assign null to a non-null variable, it'll crash with an error - because as far as the compiler's concerned, something's gone wrong.
(You should also get some warnings in your IDE if you're using one, trying to null-check a variable that you've declared as non-null will give you some "why are you trying to do this? It can't be null, right?" messages that hint that something's wrong somewhere. Also if you didn't add the !! after readLine(), you'd get a warning about that - probably why you added the !! in the first place! It doesn't make the problem go away, just stops the IDE from warning you about it)
Also you might have noticed, I made s a val instead of a var because it's a fixed value you're not going to change - always prefer vals unless you definitely need to change that variable, it's not such a big deal here but it makes some other things easier (you'll get warnings about that too)
Well, NPE is the most probably thrown from
var s:String = readLine()!!
where those !! are part of kotlin null-safety feature.
And from java doc of readLine() we can find out when is null returned.
/**
* Reads a line of input from the standard input stream.
*
* #return the line read or `null` if the input stream is redirected to a file and the end of file has been reached.
*/
fun readLine(): String? = LineReader.readLine(System.`in`, Charset.defaultCharset())
I need to create a string from a array of map in groovy.
Required string = ^(123|456|789)
At present I am doing something like below, will this cause performance issue in production box or should I use StringBuffer java class?
def getProjectList(def caseResult) {
def projectList = ""
caseResult.each { projno ->
if (projectList.length() == 0) {
projectList = "^(${projno.project_no}|"
} else {
if (projectList.indexOf(projno.project_no) == -1)
projectList+="${projno.project_no}|"
}
}
projectList = projectList.substring(0, projectList.length() - 1)
projectList += ')'
return projectList
}
I'd go for ease of reading...
def getProjectList(def caseResult) {
"^(${caseResult.project_no.join('|')})"
}
Actually, you just want the unique ones don't you?
def getProjectList(def caseResult) {
"^(${caseResult.project_no.unique().join('|')})"
}
I need to create a string from a array of map in groovy.
It would be extremely useful to define parameter type then.
The return type too.
will this cause performance issue in production box
Well, define performance issue first. Have you measured anything to think your code has any performance issues? If not, it looks like a typical "premature optimization"
should I use StringBuffer java class
If you worry about performance, then you should rather use StringBuilder, as StringBuffer is thread-safe, taking a little performance hit.
If your code suffers from anything, it's rather readability than performance.
And I recommend you this StackExchange site, dedicated to such questions - https://codereview.stackexchange.com/ - give it a try!
Well, actually after checking GString.equals() method implementation it's not a mystery why it works as it works.
public boolean equals(Object that) {
if (that instanceof GString) {
return equals((GString) that);
}
return false;
}
The question remains, is it desired behaviour, shouldn't it return true by design in this case?
With the false in place it's easy to run into quite unexpected behaviour like:
"${'1'}" in ['1', '2', '3']
...is going to return false.
Is the current behaviour a result of equals and hashCode consistency contract or could it be improved to return more accurate results?
It has been argued whether this is a bug or just "how it works"; however, it has been around for a while. What you are running into is that you are comparing a String and a GString, which are not equivalent with the same content. I had thought this behavior was modified in the current release of Groovy, but I could be wrong.
You can use the following to get the desired behavior:
("${'1'}" as String).equals('1')
This will also bite you when you use GStrings as keys in a Map or values in a Set.
First of all, I am aware of question 'Groovy String to int' and it's responses. I am a newbe to Groovy language and right now playing around some basics. The most straightforward ways to convert String to int seem to be:
int value = "99".toInteger()
or:
int value = Integer.parseInt("99")
These both work, but comments to these answers got me confused. The first methodString.toInteger() is deprecated, as stated in groovy documentation. I also assume that
Integer.parseInt() makes use of the core Java feature.
So my question is: is there any legal, pure groovy way to perform such a simple task as converting String to an int?
I might be wrong, but I think most Grooviest way would be using a safe cast "123" as int.
Really you have a lot of ways with slightly different behaviour, and all are correct.
"100" as Integer // can throw NumberFormatException
"100" as int // throws error when string is null. can throw NumberFormatException
"10".toInteger() // can throw NumberFormatException and NullPointerException
Integer.parseInt("10") // can throw NumberFormatException (for null too)
If you want to get null instead of exception, use recipe from answer you have linked.
def toIntOrNull = { it?.isInteger() ? it.toInteger() : null }
assert 100 == toIntOrNull("100")
assert null == toIntOrNull(null)
assert null == toIntOrNull("abcd")
If you want to convert a String which is a math expression, not just a single number, try groovy.lang.Script.evaluate(String expression):
print evaluate("1+1"); // note that evalute can throw CompilationFailedException
In some dynamic languages I have seen this kind of syntax:
myValue = if (this.IsValidObject)
{
UpdateGraph();
UpdateCount();
this.Name;
}
else
{
Debug.Log (Exceptions.UninitializedObject);
3;
}
Basically being able to return the last statement in a branch as the return value for a variable, not necessarily only for method returns, but they could be achieved as well.
What's the name of this feature?
Can this also be achieved in staticly typed languages such as C#? I know C# has ternary operator, but I mean using if statements, switch statements as shown above.
It is called "conditional-branches-are-expressions" or "death to the statement/expression divide".
See Conditional If Expressions:
Many languages support if expressions, which are similar to if statements, but return a value as a result. Thus, they are true expressions (which evaluate to a value), not statements (which just perform an action).
That is, if (expr) { ... } is an expression (could possible be an expression or a statement depending upon context) in the language grammar just as ?: is an expression in languages like C, C# or Java.
This form is common in functional programming languages (which eschew side-effects) -- however, it is not "functional programming" per se and exists in other language that accept/allow a "functional like syntax" while still utilizing heavy side-effects and other paradigms (e.g. Ruby).
Some languages like Perl allow this behavior to be simulated. That is, $x = eval { if (true) { "hello world!" } else { "goodbye" } }; print $x will display "hello world!" because the eval expression evaluates to the last value evaluated inside even though the if grammar production itself is not an expression. ($x = if ... is a syntax error in Perl).
Happy coding.
To answer your other question:
Can this also be achieved in staticly typed languages such as C#?
Is it a thing the language supports? No. Can it be achieved? Kind of.
C# --like C++, Java, and all that ilk-- has expressions and statements. Statements, like if-then and switch-case, don't return values and there fore can't be used as expressions. Also, as a slight aside, your example assigns myValue to either a string or an integer, which C# can't do because it is strongly typed. You'd either have to use object myValue and then accept the casting and boxing costs, use var myValue (which is still static typed, just inferred), or some other bizarre cleverness.
Anyway, so if if-then is a statement, how do you do that in C#? You'd have to build a method to accomplish the goal of if-then-else. You could use a static method as an extension to bools, to model the Smalltalk way of doing it:
public static T IfTrue(this bool value, Action doThen, Action doElse )
{
if(value)
return doThen();
else
return doElse();
}
To use this, you'd do something like
var myVal = (6 < 7).IfTrue(() => return "Less than", () => return "Greater than");
Disclaimer: I tested none of that, so it may not quite work due to typos, but I think the principle is correct.
The new IfTrue() function checks the boolean it is attached to and executes one of two delegates passed into it. They must have the same return type, and neither accepts arguments (use closures, so it won't matter).
Now, should you do that? No, almost certainly not. Its not the proper C# way of doing things so it's confusing, and its much less efficient than using an if-then. You're trading off something like 1 IL instruction for a complex mess of classes and method calls that .NET will build behind the scenes to support that.
It is a ternary conditional.
In C you can use, for example:
printf("Debug? %s\n", debug?"yes":"no");
Edited:
A compound statement list can be evaluated as a expression in C. The last statement should be a expression and the whole compound statement surrounded by braces.
For example:
#include <stdio.h>
int main(void)
{
int a=0, b=1;
a=({
printf("testing compound statement\n");
if(b==a)
printf("equals\n");
b+1;
});
printf("a=%d\n", a);
return 0;
}
So the name of the characteristic you are doing is assigning to a (local) variable a compound statement. Now I think this helps you a little bit more. For more, please visit this source:
http://www.chemie.fu-berlin.de/chemnet/use/info/gcc/gcc_8.html
Take care,
Beco.
PS. This example makes more sense in the context of your question:
a=({
int c;
if(b==a)
c=b+1;
else
c=a-1;
c;
});
In addition to returning the value of the last expression in a branch, it's likely (depending on the language) that myValue is being assigned to an anonymous function -- or in Smalltalk / Ruby, code blocks:
A block of code (an anonymous function) can be expressed as a literal value (which is an object, since all values are objects.)
In this case, since myValue is actually pointing to a function that gets invoked only when myValue is used, the language probably implements them as closures, which are originally a feature of functional languages.
Because closures are first-class functions with free variables, closures exist in C#. However, the implicit return does not occur; in C# they're simply anonymous delegates! Consider:
Func<Object> myValue = delegate()
{
if (this.IsValidObject)
{
UpdateGraph();
UpdateCount();
return this.Name;
}
else
{
Debug.Log (Exceptions.UninitializedObject);
return 3;
}
};
This can also be done in C# using lambda expressions:
Func<Object> myValue = () =>
{
if (this.IsValidObject) { ... }
else { ... }
};
I realize your question is asking about the implicit return value, but I am trying to illustrate that there is more than just "conditional branches are expressions" going on here.
Can this also be achieved in staticly
typed languages?
Sure, the types of the involved expressions can be statically and strictly checked. There seems to be nothing dependent on dynamic typing in the "if-as-expression" approach.
For example, Haskell--a strict statically typed language with a rich system of types:
$ ghci
Prelude> let x = if True then "a" else "b" in x
"a"
(the example expression could be simpler, I just wanted to reflect the assignment from your question, but the expression to demonstrate the feature could be simlpler:
Prelude> if True then "a" else "b"
"a"
.)