2009-04-11 36 views
10

Trong Scala có thể xây dựng các mẫu dựa trên các ký tự bất thường của một chuỗi bằng cách xử lý nó như là một Seq [Char].Mẫu phù hợp với một chuỗi như Seq [Char]

Một ví dụ về tính năng này được đề cập trong A Tour of Scala

Đây là mã ví dụ sử dụng có:

object RegExpTest1 extends Application { 
def containsScala(x: String): Boolean = { 
    val z: Seq[Char] = x 
    z match { 
     case Seq('s','c','a','l','a', rest @ _*) => 
       println("rest is "+rest) 
       true 
     case Seq(_*) => 
       false 
    } 
} 

}

Tôi có vấn đề với điều này là dòng thứ ba của đoạn :

val z: Seq[Char] = x 

Tại sao loại dàn diễn viên này lại cần thiết? Không nên một chuỗi hành xử như một Seq [Char] trong mọi trường hợp (trong đó sẽ bao gồm phù hợp với mô hình)? Tuy nhiên, không có chuyển đổi này, đoạn mã sẽ không hoạt động.

Trả lời

11

Không chắc chắn 100% nếu điều này đúng, nhưng trực giác của tôi nói rằng nếu không có dàn diễn viên rõ ràng này, bạn sẽ khớp với mẫu java.lang.String, không phải là điều bạn muốn.

Dàn diễn viên rõ ràng buộc trình biên dịch Scala sử dụng Predef.stringWrapper chuyển đổi ẩn; do đó, như RichString mở rộng Seq[Char], bạn có thể thực hiện đối sánh mẫu như thể chuỗi là chuỗi ký tự.

+0

Điều đó tạo ra nhiều ý nghĩa và về cơ bản là những gì tôi đã đoán. Tuy nhiên, tôi không tìm thấy trình chuyển đổi ẩn. Cảm ơn đã chỉ ra điều đó. Vì vậy, về cơ bản, đây là một sự nhượng bộ lớn cho khả năng tương tác Java, hy sinh một số loại âm thanh. –

+2

Không có âm thanh loại nào bị mất.Chuyển đổi ngầm định chỉ là trình biên dịch chèn một hàm gọi, giống như val z: Seq [Char] = string2Seq (x) –

7

Tôi sẽ lặp lại mọi thứ mà Andri nói. Đối với khả năng tương tác, các chuỗi Scala là java.lang.String s. Trong Predef, có chuyển đổi tiềm ẩn từ String đến RichString, thực hiện Seq[Char].

Một cách có lẽ đẹp hơn của mã hóa các mô hình phù hợp, mà không cần một val trung z để giữ Seq[Char]:

def containsScala(x: String): Boolean = { 
    (x: Seq[Char]) match { 
    ... 
    } 
} 
17

Có một số lạm dụng thực sự của thuật ngữ xảy ra trong câu hỏi và ý kiến. Không có diễn viên nào trong đoạn mã này, và đặc biệt "Vì vậy, về cơ bản, đây là một sự nhượng bộ lớn đối với khả năng tương tác Java, hy sinh một số loại âm thanh" không có cơ sở trong thực tế.

Một dàn diễn viên trông giống như sau: x.asInstanceOf[Y].
Những gì bạn thấy ở trên là một bài tập: val z: Seq[Char] = x

chuyển nhượng này là hợp pháp bởi vì có một chuyển đổi ngầm String-Seq[Char]. Tôi nhấn mạnh lần nữa, đây không phải là một diễn viên. Một diễn viên là một khẳng định tùy ý mà có thể thất bại trong thời gian chạy. Không có cách nào để chuyển đổi ngầm không thành công.

Sự cố với tùy thuộc vào chuyển đổi tiềm ẩn giữa các loại và câu trả lời cho câu hỏi ban đầu, đó là chuyển đổi tiềm ẩn chỉ diễn ra nếu giá trị ban đầu không kiểm tra. Vì nó hoàn toàn hợp pháp để phù hợp trên một Chuỗi, không có chuyển đổi nào diễn ra, trận đấu không thành công.

+1

Sự nhượng bộ là String không thể kế thừa trực tiếp từ Seq [Char] vì nó là typedef đối với kiểu Java. –

+2

Xin lỗi, bạn nói đúng rằng có một sự nhượng bộ các loại (trên thực tế là scala đang bơi với chúng) mà không có bất kỳ sự mất mát nào về âm thanh, có nghĩa là một cái gì đó cụ thể và không bị ảnh hưởng ở đây. – extempore

Các vấn đề liên quan