Total Default Cost

Say I have a class:

class SomeClass[+A <: AnyRef, +B <: Any] 

To indicate this, I always need to specify types of common parameters. That is, to indicate its most general version as the type of the method parameter, I have to def someMethod(param1: SomeClass[AnyRef, Any]) or new SomeClass[AnyRef, Any] to create an instance. This becomes a major pain when it comes to more complex types that have complex generics.

Is there a way to make the [AnyRef, Any] implied when I do not provide general information? For example def someMethod(param1: SomeClass) ?

Is there any way _ could help me solve this problem and how?

PS I apologize for not initially raising the question so clearly.

+6
source share
4 answers

As suggested in my comment, doing something like this can save some typifications and is pretty simple:

 type SomeClassAny = SomeClass[AnyRef, Any] 
+7
source

If you don’t really care about what type of thing this will have, you can parameterize it with [_, _]. Examples are things like

 val thing = new SomeClass[_, _]() 

or

 def thingDoer(sc: SomeClass[_, _]) { /* Stuff */ } 

To be more understandable in nature, an underscore is called an "existential type", and it is basically equivalent to a raw type in Java, and it can also function like a Java lookup pattern. For example, this schizophrenic Java code

 public void thingThatTakesAMapList(List<? extends Map> mapList) { /* Whatever */ } 

matches this scala code

 def thingThatTakesAMapList(mapList: List[_ <: Map[_, _]]) { /* Some incredibly wild subroutine */ } 

In addition, it is worth noting that the differences between List [Any] and List [_] ... are very subtle. This means that the first is a list of People, and the last is a list of [I don't know / care]. _ other than Any. For example, if you had a class with this signature

 class SillyClass[T <: Map[_, _]] 

it would be wrong to do it

 val thing = new SillyClass[Any]() 

while it may be valid for you to do so

 val thing = new SillyClass[HashMap[_, _]]() 

and if the function took SillyClass as a parameter, you could write

 def sillyClassTaker(sc: SillyClass[_]) 

and make sure sc will not be parameterized over type Any; it is parameterized over some unknown subclass of Map [_, _]. In other words, the underscore is a placeholder , but still requires the correct type parameters in place. So, while everything is cool and everything ... I do not recommend using it too much. If you need to do something ... wildcard-y or just don't care about type parameters, this is a good option to consider.

+5
source

How about this?

 scala> :paste // Entering paste mode (ctrl-D to finish) class SomeClass[+A <: AnyRef] object SomeClass { def apply() = new SomeClass[AnyRef] } // Exiting paste mode, now interpreting. defined class SomeClass defined module SomeClass scala> SomeClass() res47: SomeClass[AnyRef] = SomeClass@4f63b5 

Edit:

I think you want something like the default arguments, but at the type level. Unfortunately, Scala does not have such a function. You can use type aliases suggested by @hyhnhjl. It seems to me the best choice.

+3
source

This can usually be inferred from the constructor parameter types, but if the constructor does not accept any parameters, you need to explicitly specify the type. Of course, as the missing factor pointed out, you can always write a method for this so that you can print multiple characters.

+1
source

Source: https://habr.com/ru/post/904620/


All Articles