Làm cách nào để xác định một hàm có nhiều đối số ngầm định.
def myfun(arg:String)(implicit p1: String)(implicit p2:Int)={} // doesn't work
Làm cách nào để xác định một hàm có nhiều đối số ngầm định.
def myfun(arg:String)(implicit p1: String)(implicit p2:Int)={} // doesn't work
Câu trả lời:
Tất cả chúng phải nằm trong một danh sách tham số và danh sách này phải là danh sách cuối cùng.
def myfun(arg:String)(implicit p1: String, p2:Int)={}
Thực ra có một cách để thực hiện chính xác những gì OP yêu cầu. Một chút phức tạp, nhưng nó hoạt động.
class MyFunPart2(arg: String, /*Not implicit!*/ p1: String) {
def apply(implicit p2: Int) = {
println(arg+p1+p2)
/* otherwise your actual code */
}
}
def myFun(arg: String)(implicit p1: String): MyFunPart2= {
new MyFunPart2(arg, p1)
}
implicit val iString= " world! "
implicit val iInt= 2019
myFun("Hello").apply
myFun("Hello")(" my friend! ").apply
myFun("Hello")(" my friend! ")(2020)
// Output is:
// Hello world! 2019
// Hello my friend! 2019
// Hello my friend! 2020
Trong Scala 3 (hay còn gọi là "Dotty", mặc dù đây là tên của trình biên dịch) thay vì trả về một đối tượng MyFunPart2 bổ trợ , có thể trả về một giá trị hàm với các đối số ngầm định trực tiếp. Điều này là do Scala 3 hỗ trợ "Hàm ngầm" (tức là "tính không tường minh của tham số" bây giờ là một phần của các kiểu hàm). Nhiều danh sách tham số ngầm trở nên dễ triển khai đến mức có thể ngôn ngữ sẽ hỗ trợ chúng trực tiếp, mặc dù tôi không chắc.
Có một cách khác (IMO đơn giản hơn và linh hoạt hơn) để đạt được hiệu quả tương tự:
// Note the implicit is now a Tuple2
def myFun(arg: String)(implicit p: (String, Int) ): Unit = {
println(arg + p._1 + p._2)
/*otherwise your actual code*/
}
// These implicit conversion are able to produce the basic implicit (String,Int) Tuples
implicit def idis(implicit is: String, ii: Int): (String,Int)= (is,ii)
implicit def idi(s: String)(implicit ii: Int): (String,Int)= (s,ii)
// The basic implicit values for both underlying parameters
implicit val iString = " world! "
implicit val iInt = 2019
myFun("Hello")
myFun("Hello")(" my friend! ")
myFun("Hello")(" my friend! ",2020)
// Output is:
// Hello world! 2019
// Hello my friend! 2019
// Hello my friend! 2020
// If we add the following implicit,
implicit def ids(i: Int)(implicit is: String)= (is,i)
// we can even do
myFun("Hello")(2020)
// , and output is:
// Hello world! 2020
Sử dụng Tuple làm đại diện cơ bản cho các tham số không phải là một ý tưởng hay vì các chuyển đổi ngầm định có thể ảnh hưởng đến các mục đích sử dụng khác. Trên thực tế, các chuyển đổi ngầm định sang bất kỳ loại tiêu chuẩn nào (bao gồm cả loại thư viện) thường gây ra rắc rối trong bất kỳ ứng dụng không tầm thường nào. Giải pháp là tạo một lớp trường hợp chuyên dụng để giữ các tham số thay vì một Tuple. Một lợi thế quan trọng là chúng có thể được đặt những cái tên có ý nghĩa hơn _1 và _2.