2017-09-03 15 views
15

Xem mã ví dụ này trong Kotlin:Tại sao Kotlin chức năng với các thông số mặc định tạo ra một phương thức với tham số chưa sử dụng

fun foo(bar: Int = 0, baz: Int) { 
    /* ... */ 
} 

Sau khi dịch ngược nó để mã Java (Tools -> Kotlin -> Show Kotlin Bytecode -> Decompile) Tôi nhận được mã sau đây

public static final void foo(int bar, int baz) { 
} 

// $FF: synthetic method 
// $FF: bridge method 
public static void foo$default(int var0, int var1, int var2, Object var3) { 
    if ((var2 & 1) != 0) { 
    var0 = 0; 
    } 

    foo(var0, var1); 
} 

Tôi nhận thấy rằng phương thức Java kết quả có tham số Object var3 không sử dụng.

tôi loại nghĩ rằng nó có thể liên quan đến chức năng trong một lớp học nhưng khi dịch ngược mã này

class Foo { 
    fun foo(bar: Int = 0, baz: Int) { 
     /* ... */ 
    } 
} 

Tôi có mã này

public final class Foo { 
    public final void foo(int bar, int baz) { 
    } 

    // $FF: synthetic method 
    // $FF: bridge method 
    public static void foo$default(Foo var0, int var1, int var2, int var3, Object var4) { 
     if ((var3 & 1) != 0) { 
     var1 = 0; 
     } 

     var0.foo(var1, var2); 
    } 
} 

Như bạn có thể thấy các thông số Object vẫn là không sử dụng và chỉ ngồi đó. Khi thử nghiệm bổ sung, tôi nhận thấy hành vi tương tự cho các phương pháp mở rộng. Cũng vậy khi các tham số mặc định là cuối cùng (tức là fun foo(bar: Int, baz: Int = 0) {})

Tôi cũng đã thực hiện một thử nghiệm cơ bản để kiểm tra xem giá trị thiết lập để khi gọi hàm bằng cách sử dụng đoạn mã sau

fun main(args: Array<String>) { 
    foo(baz = 2) 
} 

là gì
class Something { 
    init { 
     foo(baz = 2) 
    } 
} 

sau khi dịch ngược nó tôi có đoạn mã sau

public static final void main(@NotNull String[] args) { 
     Intrinsics.checkParameterIsNotNull(args, "args"); 
     foo$default(0, 2, 1, (Object)null); 
} 

public final class Something { 
    public Something() { 
     FooKt.foo$default(0, 2, 1, (Object)null); 
    } 
} 

Điều này thậm chí còn ít ý nghĩa hơn.

Câu hỏi của tôi là: Tại sao Kotlin tạo tham số không sử dụng cho các hàm có tham số mặc định? Nó là một lỗi?

+0

những gì bạn nhận được khi các thông số mặc định của bạn là cuối cùng? như trong 'fun foo (bar: Int, baz: Int = 0) {}' – Les

+0

@Les vừa kiểm tra. Nó giống nhau (tức là đối tượng kỳ lạ var được tạo ra) – Mibac

+0

bạn đã thử thực hiện cuộc gọi chưa và xem đối tượng được truyền trong mã java là gì? – DPM

Trả lời

6

Theo this, hiện tại nó không được sử dụng, nhưng được dành riêng để thêm siêu cuộc gọi với các giá trị mặc định sau.

Bạn có thể nhìn thấy nó trong hành động ở đây:

open class Foo { 
    open fun foo(bar: Int = 0, baz: Int) { 
     /* ... */ 
    } 
} 

class Blah: Foo() { 
    override fun foo(bar: Int, baz: Int) { 
    } 
} 

mà sẽ tạo ra một bytecode-to-Java Foo của:

public class Foo { 
    public void foo(int bar, int baz) { 
    } 

    // $FF: synthetic method 
    // $FF: bridge method 
    public static void foo$default(Foo var0, int var1, int var2, int var3, Object var4) { 
     if(var4 != null) { 
     throw new UnsupportedOperationException("Super calls with default arguments not supported in this target, function: foo"); 
     } else { 
     if((var3 & 1) != 0) { 
      var1 = 0; 
     } 

     var0.foo(var1, var2); 
     } 
    } 
} 
Các vấn đề liên quan