I have been developing in Groovy for a little while now and I’m wondering how often I should be using the dynamic casting def
? A co-worker of mine believes we should use it always as it helps Groovy in some way I don’t understand.
Currently, when declaring method return types and arguments, I like to deliberately state which objects should be taken in and spit out (for code readability and I come from a Java background it makes sense to me) example:
String doSomething(String something){
//code
}
// vs
def doSomething(def somthing){
//code
}
// vs
def doSomething(somthing){
// code
}
So I guess my question is it just a preference of when to use def
or is there a real advantage to using it all the time? (I added the last example because I felt it fits in with the question as a viable option for Groovy)
3
As good programming (even scripting) practice, always consider specifying a definite (though not necessarily concrete) type for a variable. Use def
only if there’s no definite type applicable to the variable.
Since the OP knows Java, it’s no different from specifying a type of Object
(though there seems to be a minor difference). The answer to this question then won’t be different from answering a question like: “why not always use the Object
type in Java?”
Being as definite about types as possible reduces the chances of bugs, and even serves as self-documentation. Whereas, if one is deliberately implementing a dynamic logic, then using def
might make a lot of sense. That’s in fact one of the biggest strengths of Groovy; the program can be as dynamically or statically typed as one needs it to be! Just don’t let laziness be the reason to use def
😉
E.g. this method makes sense with a definite argument type and return type:
// def val or Object val, opens up the possibility
// of the caller sending a non-numeric value
Number half(Number val) {
val/2
}
while this method makes sense with type def
// I'd let them pass an argument of any type;
// type `Object` makes sense too
def getIdProperty(def val) {
if(val?.hasProperty('id')) {
// I don't know the type of this returned
// value and I don't really need to care
return val.id
}
else {
throw new IllegalArgumentException("Argument doesn't have an 'id' property")
}
}
Whenever the code you’re writing is going to be used by others as a public API, you should always favor the use of strong typing, it helps making the contract stronger, avoids possible passed arguments type mistakes, gives better documentation, and also helps the IDE with code completion. Whenever the code is for your use only, like private methods, or when the IDE can easily infer the type, then you’re more free to decide when to type or not.
1