This is the second heavy learning Kotlin series, in this paper, a permanent update address: https://xiaozhuanlan.com/topic/0846175293.

Maybe I don’t even know him.

Today’s story is about type aliases. Let’s take a look at the table of contents:

  1. What is TypeAlias?
  2. The essence of typealias
  3. What is the purpose of the TypeAlias?
  4. Notes for using TypeAlias

What is TypeAlias?

This is a very basic keyword, but probably not used by many people. What it does is simple: Give an alias to an existing type. You can use the “type alias” just as you would use the original type.

Here’s a simple example:

typealias Name = String
val name : Name = "java"
println(name.length)
Copy the code

Give a String its own Name, Name. In use, Name and String are exactly the same.

Since they are equivalent, what is the point of using an alias?

Don’t worry, TypeAlias doesn’t just support aliasing classes; it can be used in more ways than you’d think.

// Class and interface
typealias Name = String
typealias Data = Serializable

// Function type
typealias GetName = () -> String typealias Handler = CoroutineScope.() -> Unit  / / generics typealias P<T> = Comparable<T> typealias Pairs<K, V> = HashMap<K, V> typealias Numbers = Array<Number>  // object object Single {} typealias X = Single  class Util {  companion object {  val count = 1  } } typealias Count = Util.Companion  // inner class typealias NotificationBuilder = NotificationCompat.Builder  class Outer { inner class Inner } typealias In = Outer.Inner  / / the enumeration enum class Color { RED, YELLOW, GREEN } typealias color = Color  / / comment typealias Jvm = JvmStatic Copy the code

One thing to note about the above use of enumeration is that you can alias only the enumeration class Color, not the specific enumeration value. Such as TypeAlias Red = Color. Red is not allowed.

There are few types that typeAlias does not apply to. At this point, you have to ask, what is the point of type aliases? Why not just use the original type?

The essence of typealias

Before you worry, let’s take a look at how typeAlias works and see if you can find something.

Decompile the following simple example:

typealias Binary = ByteArray
fun getBinary(string: String) : Binary = string.toByteArray()
Copy the code

Take a look at the Java code:

public final class TypealiasKt {
   @NotNull
   public static final byte[] getBinary(@NotNull String string) {
      Intrinsics.checkParameterIsNotNull(string, "string");
      Charset var2 = Charsets.UTF_8;
 boolean var3 = false;  byte[] var10000 = string.getBytes(var2);  Intrinsics.checkExpressionValueIsNotNull(var10000, "(this as java.lang.String).getBytes(charset)");  return var10000;  } } Copy the code

The type alias Binary is nowhere to be found in the code. After compilation, the type alias is replaced directly by the original type. This is just one of Kotlin’s rich syntactic sweets, and the compiler has played some tricks with them.

What is the purpose of the TypeAlias?

Now, you’re probably even more confused.

The developer manually declares a type alias, which the compiler automatically replaces back to the original type. What’s the point?

The only thing that comes to mind is probably “code readability,” with a big quote mark around it.

Complex business logic, your code may have long names, multi-parameter, multi-generic type class names, interface names, function names.

typealias FileTable<K> = MutableMap<K, MutableList<File>>
typealias OnPermissionResult = ActivityCompat.OnRequestPermissionsResultCallback
typealias SimpleName = LonglonglonglonglonglonglonglonglonglonglonglonglonglonglongName
Copy the code

Replacing otherwise unreadable (too long or complex to declare) type names with type aliases is probably the primary purpose of TypeAliases.

Does it improve readability? I think there’s a price. What is lost is intuitive type declarations. Take the example of FileTable in the above code block. At first glance, can you see that it is a MutableMap

>? Certainly not. Especially in team development, it is possible that everyone except the contributor to this code will have to look at the type alias declaration.
,>

Someone might have a different voice. Uniform global declarations are common, and they make it easier to make uniform changes without having to go all the way to the code. In addition, the IDE will automatically prompt declarations of type aliases. There is no reason not to use typeAlias.

So, it’s a matter of opinion. You can use it if you think it’s useful, and every technology has its uses, so there’s no need to argue about it too much.

Do I use coroutines or RxJava? Do I use LiveData or the event bus? Do I use ViewBinding or DataBinding? .

These questions may be common, but for each set of choices, if you really dig into the nature of the technology, they are used in different scenarios, and there is no question of how to choose.

Notes for using TypeAlias

A little bit off track, go back to TypeAlias. Here are some typeAlias considerations, which will be somewhat fragmented and may be added later.

Where can TYPEAlias be written?

It can only be declared at the top of the file, not anywhere else.

How do I interact with Java?

Refuse to interact with Java.

No nesting dolls!

We can give aliases as follows:

typealias Names<T> = Array<T>
typealias SubNames<T> = Names<T>
Copy the code

It doesn’t make much sense, but it’s grammatically correct.

This is definitely not going to work.

typealias R = R

typealias L = List<L>
typealias A<T> = List<A<T>>

typealias R1 = (Int) -> R2 typealias R2 = (R1) -> Int Copy the code

Each line of code above is uncompilable.

visibility

The Top-level typeAlias can use the visibility modifiers public, private, and internal. At the same time, TypeAlias cannot change the visibility of an existing type. Here’s an example:

private class LongName{}
typealias ShortName = LongName // 'public' typealias exposes 'private' in expanded type LongName
Copy the code

The above code will fail to compile and the public type alias will not apply to the private original type. The visibility of the type alias and the original type must be consistent.

Import the processing of a class with the same name

For importing two classes with the same name in the same class, it is common to import one class and the other with a fully qualified name. As follows:

fun main(a) {
    val user1 = User()
    val user2 = com.test2.User()
}
Copy the code

This is more or less aesthetic and can be handled using typeAlias.

typealias User2 = com.test2.User

fun main(a) {
    val user1 = User()
    val user2 = User2()
} Copy the code

Also, import… as … Can also solve this problem.

import com.test1.User
import com.test2.User as User2

fun main(a) {
    val user1 = User()
 val user2 = User2() } Copy the code

The last

Look through your code base for “bad” names that can be optimized using TypeAlias. If so, feel free to share in the comments section.

Previous catalog: Object, the fastest singleton ever?

This article is formatted using MDNICE