Câu hỏi Làm thế nào để phù hợp với mô hình đối với mọi lớp số trong một trường hợp?


Giả sử tôi có

def foo(x: Any) = x match {
  case s: String => println(0)
  case i: Int => println(1)
  case l: Long => println(2)
  //...
}

Có cách nào để làm một cái gì đó như sau?

def foo(x: Any) = x match {
  case s: String => println(0)
  case i: Numeric => println("Numeric")
}

7
2017-11-03 19:31


gốc




Các câu trả lời:


Bạn có thể phù hợp với Number giao diện:

def foo(x: Any) = x match {
  case s: String => println(0)
  case i: java.lang.Number => println("Numeric")
}

4
2017-11-03 19:43



Cảm ơn bạn, làm việc như một say mê. - tkroman
Loại kết hợp này không được khuyến khích vì nó là từ đồng nghĩa với kiểu đúc, điều này là có thể nhưng được coi là 'kiểu xấu' trong lập trình hàm. - Rajish
Cũng không có cách thành ngữ nào ở đây, vì vậy điều này được khuyến khích cho kịch bản này - cho đến khi Scala bắt kịp với Java .. - matanster


Bạn có thể thử điều này:

def foo[A](x: A)(implicit num: Numeric[A] = null) = Option(num) match {
  case Some(num) => println("Numeric: " + x.getClass.getName)
  case None => println(0)
}

Thì đây

foo(1)
foo(2.0)
foo(BigDecimal(3))
foo('c')
foo("no")

sẽ in

Numeric: java.lang.Integer
Numeric: java.lang.Double
Numeric: scala.math.BigDecimal
Numeric: java.lang.Character
0

Lưu ý rằng có được một null tham số ngầm định sẽ không có nghĩa là không tồn tại tiềm ẩn như vậy, nhưng chỉ có không có tham số nào được tìm thấy tại thời gian biên dịch trong phạm vi tìm kiếm cho các implicit.


3
2017-11-03 19:43



Đó là một điều khó khăn! Thật đáng tiếc tôi không thể chấp nhận cả hai câu trả lời. - tkroman
Có cách nào tốt đẹp để tránh null giá trị? (Ví dụ: cung cấp tiềm ẩn Option[Numeric[A]]?) - r0estir0bbe
Tất cả các thủ thuật mà tôi có thể nghĩ đến sẽ ít đáng kể hơn và không an toàn hơn nhiều. - Jean-Philippe Pellet
Đó là những gì tôi nghi ngờ. Cảm ơn bạn đã làm rõ! - r0estir0bbe
Tôi nhận thấy rằng giải pháp này không hoạt động nếu các giá trị số được nhập Any và sau đó được chuyển đến phương pháp, ví dụ: val x: Any = 3.14; foo(x) sẽ in 0. Trong trường hợp đó, chỉ có giải pháp của câu trả lời được chấp nhận là làm việc như dự định. Tôi cần chức năng này vì tôi muốn trích xuất bất kỳ giá trị số nào double từ Map[String, Any]. Có cách nào để thay đổi phương pháp này để làm việc với Any cũng? Tôi thích sử dụng Numeric thay vì khớp mẫu java.lang.Number. - r0estir0bbe