Bảng cheat spark scala

Dành cho các nhà khoa học và nhà phân tích dữ liệu quan tâm đến các phân tích có thể mở rộng được hỗ trợ bởi các thuật toán đồ thị và mô hình máy học

Thư viện GDS AuraDS

Neo4j Bloom và các công cụ khác

Hệ quản trị cơ sở dữ liệu Neo4j

Bảng cheat spark scala

Tìm hiểu cách khám phá biểu đồ của bạn với Neo4j Bloom và các công cụ khác, chẳng hạn như Neo4j Desktop, Neo4j Browser và Neo4j Ops Manager

công cụ neo4j

bảo mật neo4j

Tài liệu bảo mật

Bảng cheat spark scala

Đi thẳng vào phần bảo mật trong tài liệu sản phẩm của chúng tôi và tìm nội dung hữu ích khác liên quan đến bảo mật

Tài liệu bảo mật

Phiên bản cũ hơn và PDF

  • Tài liệu cho các bản phát hành trước đó có sẵn từ bộ chọn phiên bản trên mỗi trang. Để có danh sách đầy đủ, vui lòng xem kho lưu trữ Tài liệu của chúng tôi

  • Ngoài ra, hầu hết các tài liệu của chúng tôi đều có sẵn dưới dạng PDF có thể tải xuống. Để biết danh sách đầy đủ các tệp PDF có sẵn, hãy xem thư viện PDF

    Phản ánh là khả năng của một chương trình để kiểm tra và thậm chí có thể tự sửa đổi. Nó có một lịch sử lâu dài trên các mô hình lập trình hướng đối tượng, chức năng và logic. Trong khi một số ngôn ngữ được xây dựng xung quanh sự phản ánh như một nguyên tắc hướng dẫn, nhiều ngôn ngữ dần dần phát triển khả năng phản ánh của chúng theo thời gian

    Sự phản ánh liên quan đến khả năng cụ thể hóa (i. e. làm rõ ràng) các phần tử ngầm ẩn khác của một chương trình. Các phần tử này có thể là phần tử chương trình tĩnh như lớp, phương thức hoặc biểu thức hoặc phần tử động như sự kiện tiếp tục hoặc thực thi hiện tại, chẳng hạn như lời gọi phương thức và truy cập trường. Người ta thường phân biệt giữa phản ánh thời gian biên dịch và thời gian chạy tùy thuộc vào thời điểm quá trình phản chiếu được thực hiện. Phản ánh thời gian biên dịch là một cách mạnh mẽ để phát triển các trình biến đổi và trình tạo chương trình, trong khi phản ánh thời gian chạy thường được sử dụng để điều chỉnh ngữ nghĩa ngôn ngữ hoặc để hỗ trợ liên kết rất muộn giữa các thành phần phần mềm

    Cho đến 2. 10, Scala không có bất kỳ khả năng phản chiếu nào của riêng nó. Thay vào đó, người ta có thể sử dụng một phần của API phản chiếu Java, cụ thể là xử lý việc cung cấp khả năng kiểm tra động các lớp và đối tượng và truy cập các thành viên của chúng. Tuy nhiên, nhiều phần tử dành riêng cho Scala không thể phục hồi dưới sự phản chiếu Java độc lập, chỉ hiển thị các phần tử Java (không có chức năng, không có đặc điểm) và các loại (không có loại tồn tại, loại cao hơn, phụ thuộc vào đường dẫn và loại trừu tượng). Ngoài ra, phản ánh Java cũng không thể khôi phục thông tin loại thời gian chạy của các loại Java chung tại thời điểm biên dịch;

    Trong Scala 2. Vào ngày 10 tháng 10, một thư viện phản chiếu mới đã được giới thiệu không chỉ để giải quyết những thiếu sót trong phản ánh thời gian chạy của Java đối với các loại chung và cụ thể của Scala, mà còn bổ sung một bộ công cụ mạnh mẽ hơn về các khả năng phản chiếu chung cho Scala. Cùng với phản ánh thời gian chạy đầy đủ tính năng cho các loại Scala và generic, Scala 2. 10 cũng có khả năng phản ánh thời gian biên dịch, ở dạng macro, cũng như khả năng thống nhất các biểu thức Scala thành các cây cú pháp trừu tượng

    phản ánh thời gian chạy là gì?

    • kiểm tra loại đối tượng đó, bao gồm các loại chung chung,
    • để khởi tạo các đối tượng mới,
    • hoặc để truy cập hoặc gọi các thành viên của đối tượng đó

    Hãy bắt đầu và xem cách thực hiện từng điều trên với một vài ví dụ

    ví dụ

    Cũng như các ngôn ngữ JVM khác, các kiểu của Scala bị xóa tại thời điểm biên dịch. Điều này có nghĩa là nếu bạn kiểm tra loại thời gian chạy của một số phiên bản, thì bạn có thể không có quyền truy cập vào tất cả thông tin loại mà trình biên dịch Scala có sẵn tại thời điểm biên dịch

    Các

    scala> val decls = theType.decls.take(10)
    decls: Iterable[ru.Symbol] = List(constructor List, method companion, method isEmpty, method head, method tail, method ::, method :::, method reverse_:::, method mapConserve, method ++)
    
    6 có thể được coi là các đối tượng mang theo tất cả các loại thông tin có sẵn tại thời điểm biên dịch, thời gian chạy. Mặc dù vậy, điều quan trọng cần lưu ý là các
    scala> val decls = theType.decls.take(10)
    decls: Iterable[ru.Symbol] = List(constructor List, method companion, method isEmpty, method head, method tail, method ::, method :::, method reverse_:::, method mapConserve, method ++)
    
    6 luôn được tạo bởi trình biên dịch. Quá trình tạo này được kích hoạt bất cứ khi nào một tham số ẩn hoặc ràng buộc ngữ cảnh yêu cầu sử dụng
    scala> val decls = theType.decls.take(10)
    decls: Iterable[ru.Symbol] = List(constructor List, method companion, method isEmpty, method head, method tail, method ::, method :::, method reverse_:::, method mapConserve, method ++)
    
    6. Điều này có nghĩa là, thông thường, người ta chỉ có thể nhận được một
    scala> val decls = theType.decls.take(10)
    decls: Iterable[ru.Symbol] = List(constructor List, method companion, method isEmpty, method head, method tail, method ::, method :::, method reverse_:::, method mapConserve, method ++)
    
    6 bằng cách sử dụng các tham số ẩn hoặc giới hạn ngữ cảnh

    Ví dụ: sử dụng giới hạn ngữ cảnh

    scala> import scala.reflect.runtime.{universe => ru}
    import scala.reflect.runtime.{universe=>ru}
    
    scala> val l = List(1,2,3)
    l: List[Int] = List(1, 2, 3)
    
    scala> def getTypeTag[T: ru.TypeTag](obj: T) = ru.typeTag[T]
    getTypeTag: [T](obj: T)(implicit evidence$1: ru.TypeTag[T])ru.TypeTag[T]
    
    scala> val theType = getTypeTag(l).tpe
    theType: ru.Type = List[Int]
    

    Ở phần trên, trước tiên chúng tôi nhập

    scala> case class Person(name: String)
    defined class Person
    
    scala> val m = ru.runtimeMirror(getClass.getClassLoader)
    m: scala.reflect.runtime.universe.Mirror = JavaMirror with ...
    
    0 (phải luôn nhập để sử dụng các
    scala> val decls = theType.decls.take(10)
    decls: Iterable[ru.Symbol] = List(constructor List, method companion, method isEmpty, method head, method tail, method ::, method :::, method reverse_:::, method mapConserve, method ++)
    
    6) và chúng tôi tạo một
    scala> case class Person(name: String)
    defined class Person
    
    scala> val m = ru.runtimeMirror(getClass.getClassLoader)
    m: scala.reflect.runtime.universe.Mirror = JavaMirror with ...
    
    2 có tên là
    scala> case class Person(name: String)
    defined class Person
    
    scala> val m = ru.runtimeMirror(getClass.getClassLoader)
    m: scala.reflect.runtime.universe.Mirror = JavaMirror with ...
    
    3. Sau đó, chúng tôi xác định một phương thức
    scala> case class Person(name: String)
    defined class Person
    
    scala> val m = ru.runtimeMirror(getClass.getClassLoader)
    m: scala.reflect.runtime.universe.Mirror = JavaMirror with ...
    
    4 có tham số loại
    scala> case class Person(name: String)
    defined class Person
    
    scala> val m = ru.runtimeMirror(getClass.getClassLoader)
    m: scala.reflect.runtime.universe.Mirror = JavaMirror with ...
    
    5 có giới hạn ngữ cảnh (như REPL cho thấy, điều này tương đương với việc xác định tham số "bằng chứng" ngầm định, khiến trình biên dịch tạo ra một
    scala> val decls = theType.decls.take(10)
    decls: Iterable[ru.Symbol] = List(constructor List, method companion, method isEmpty, method head, method tail, method ::, method :::, method reverse_:::, method mapConserve, method ++)
    
    6 cho
    scala> case class Person(name: String)
    defined class Person
    
    scala> val m = ru.runtimeMirror(getClass.getClassLoader)
    m: scala.reflect.runtime.universe.Mirror = JavaMirror with ...
    
    5). Cuối cùng, chúng tôi gọi phương thức của mình với
    scala> case class Person(name: String)
    defined class Person
    
    scala> val m = ru.runtimeMirror(getClass.getClassLoader)
    m: scala.reflect.runtime.universe.Mirror = JavaMirror with ...
    
    3 dưới dạng tham số của nó và gọi
    scala> case class Person(name: String)
    defined class Person
    
    scala> val m = ru.runtimeMirror(getClass.getClassLoader)
    m: scala.reflect.runtime.universe.Mirror = JavaMirror with ...
    
    9 trả về loại có trong
    scala> val decls = theType.decls.take(10)
    decls: Iterable[ru.Symbol] = List(constructor List, method companion, method isEmpty, method head, method tail, method ::, method :::, method reverse_:::, method mapConserve, method ++)
    
    6. Như chúng ta có thể thấy, chúng ta nhận được loại chính xác, đầy đủ (bao gồm cả đối số loại cụ thể của
    scala> val decls = theType.decls.take(10)
    decls: Iterable[ru.Symbol] = List(constructor List, method companion, method isEmpty, method head, method tail, method ::, method :::, method reverse_:::, method mapConserve, method ++)
    
    61),
    scala> case class Person(name: String)
    defined class Person
    
    scala> val m = ru.runtimeMirror(getClass.getClassLoader)
    m: scala.reflect.runtime.universe.Mirror = JavaMirror with ...
    
    2

    Khi chúng tôi đã có được phiên bản

    scala> val decls = theType.decls.take(10)
    decls: Iterable[ru.Symbol] = List(constructor List, method companion, method isEmpty, method head, method tail, method ::, method :::, method reverse_:::, method mapConserve, method ++)
    
    63 mong muốn, chúng tôi có thể kiểm tra nó, e. g

    scala> val decls = theType.decls.take(10)
    decls: Iterable[ru.Symbol] = List(constructor List, method companion, method isEmpty, method head, method tail, method ::, method :::, method reverse_:::, method mapConserve, method ++)
    

    Các loại thu được thông qua phản xạ có thể được khởi tạo bằng cách gọi hàm tạo của chúng bằng cách sử dụng một gương "gọi" thích hợp (các gương được mở rộng bên dưới). Hãy xem qua một ví dụ sử dụng REPL

    scala> case class Person(name: String)
    defined class Person
    
    scala> val m = ru.runtimeMirror(getClass.getClassLoader)
    m: scala.reflect.runtime.universe.Mirror = JavaMirror with ...
    

    Trong bước đầu tiên, chúng tôi có được một bản sao

    scala> val decls = theType.decls.take(10)
    decls: Iterable[ru.Symbol] = List(constructor List, method companion, method isEmpty, method head, method tail, method ::, method :::, method reverse_:::, method mapConserve, method ++)
    
    64 cung cấp tất cả các lớp và loại được tải bởi trình nạp lớp hiện tại, bao gồm cả lớp
    scala> val decls = theType.decls.take(10)
    decls: Iterable[ru.Symbol] = List(constructor List, method companion, method isEmpty, method head, method tail, method ::, method :::, method reverse_:::, method mapConserve, method ++)
    
    65

    scala> val decls = theType.decls.take(10)
    decls: Iterable[ru.Symbol] = List(constructor List, method companion, method isEmpty, method head, method tail, method ::, method :::, method reverse_:::, method mapConserve, method ++)
    
    6

    Bước thứ hai liên quan đến việc lấy một

    scala> val decls = theType.decls.take(10)
    decls: Iterable[ru.Symbol] = List(constructor List, method companion, method isEmpty, method head, method tail, method ::, method :::, method reverse_:::, method mapConserve, method ++)
    
    66 cho lớp
    scala> val decls = theType.decls.take(10)
    decls: Iterable[ru.Symbol] = List(constructor List, method companion, method isEmpty, method head, method tail, method ::, method :::, method reverse_:::, method mapConserve, method ++)
    
    65 bằng cách sử dụng phương pháp
    scala> val decls = theType.decls.take(10)
    decls: Iterable[ru.Symbol] = List(constructor List, method companion, method isEmpty, method head, method tail, method ::, method :::, method reverse_:::, method mapConserve, method ++)
    
    68.
    scala> val decls = theType.decls.take(10)
    decls: Iterable[ru.Symbol] = List(constructor List, method companion, method isEmpty, method head, method tail, method ::, method :::, method reverse_:::, method mapConserve, method ++)
    
    66 cung cấp quyền truy cập vào hàm tạo của lớp
    scala> val decls = theType.decls.take(10)
    decls: Iterable[ru.Symbol] = List(constructor List, method companion, method isEmpty, method head, method tail, method ::, method :::, method reverse_:::, method mapConserve, method ++)
    
    65. (Nếu bước này gây ra ngoại lệ, cách giải quyết dễ dàng là sử dụng các cờ này khi bắt đầu REPL.
    scala> val decls = theType.decls.take(10)
    decls: Iterable[ru.Symbol] = List(constructor List, method companion, method isEmpty, method head, method tail, method ::, method :::, method reverse_:::, method mapConserve, method ++)
    
    91)

    scala> val decls = theType.decls.take(10)
    decls: Iterable[ru.Symbol] = List(constructor List, method companion, method isEmpty, method head, method tail, method ::, method :::, method reverse_:::, method mapConserve, method ++)
    
    9

    Có thể lấy ký hiệu cho hàm tạo của

    scala> val decls = theType.decls.take(10)
    decls: Iterable[ru.Symbol] = List(constructor List, method companion, method isEmpty, method head, method tail, method ::, method :::, method reverse_:::, method mapConserve, method ++)
    
    65 chỉ bằng cách sử dụng vũ trụ thời gian chạy
    scala> val decls = theType.decls.take(10)
    decls: Iterable[ru.Symbol] = List(constructor List, method companion, method isEmpty, method head, method tail, method ::, method :::, method reverse_:::, method mapConserve, method ++)
    
    93 bằng cách tra cứu nó trong các khai báo của loại
    scala> val decls = theType.decls.take(10)
    decls: Iterable[ru.Symbol] = List(constructor List, method companion, method isEmpty, method head, method tail, method ::, method :::, method reverse_:::, method mapConserve, method ++)
    
    65

    scala> val decls = theType.decls.take(10)
    decls: Iterable[ru.Symbol] = List(constructor List, method companion, method isEmpty, method head, method tail, method ::, method :::, method reverse_:::, method mapConserve, method ++)
    
    4

    Truy cập và gọi các thành viên của các loại thời gian chạy

    Nói chung, các thành viên của các loại thời gian chạy được truy cập bằng cách sử dụng máy nhân bản "người gọi" thích hợp (các máy nhân bản được mở rộng ở bên dưới). Hãy xem qua một ví dụ sử dụng REPL

    scala> val decls = theType.decls.take(10)
    decls: Iterable[ru.Symbol] = List(constructor List, method companion, method isEmpty, method head, method tail, method ::, method :::, method reverse_:::, method mapConserve, method ++)
    
    5

    Trong ví dụ này, chúng tôi sẽ cố gắng lấy và đặt trường

    scala> val decls = theType.decls.take(10)
    decls: Iterable[ru.Symbol] = List(constructor List, method companion, method isEmpty, method head, method tail, method ::, method :::, method reverse_:::, method mapConserve, method ++)
    
    95 của
    scala> val decls = theType.decls.take(10)
    decls: Iterable[ru.Symbol] = List(constructor List, method companion, method isEmpty, method head, method tail, method ::, method :::, method reverse_:::, method mapConserve, method ++)
    
    96
    scala> val decls = theType.decls.take(10)
    decls: Iterable[ru.Symbol] = List(constructor List, method companion, method isEmpty, method head, method tail, method ::, method :::, method reverse_:::, method mapConserve, method ++)
    
    97, một cách phản ánh

    scala> val decls = theType.decls.take(10)
    decls: Iterable[ru.Symbol] = List(constructor List, method companion, method isEmpty, method head, method tail, method ::, method :::, method reverse_:::, method mapConserve, method ++)
    
    9

    Như chúng tôi đã làm trong ví dụ trước, chúng tôi sẽ bắt đầu bằng cách lấy một máy nhân bản

    scala> val decls = theType.decls.take(10)
    decls: Iterable[ru.Symbol] = List(constructor List, method companion, method isEmpty, method head, method tail, method ::, method :::, method reverse_:::, method mapConserve, method ++)
    
    64, cung cấp tất cả các lớp và loại được tải bởi trình nạp lớp cũng đã tải lớp
    scala> val decls = theType.decls.take(10)
    decls: Iterable[ru.Symbol] = List(constructor List, method companion, method isEmpty, method head, method tail, method ::, method :::, method reverse_:::, method mapConserve, method ++)
    
    97 (
    scala> val decls = theType.decls.take(10)
    decls: Iterable[ru.Symbol] = List(constructor List, method companion, method isEmpty, method head, method tail, method ::, method :::, method reverse_:::, method mapConserve, method ++)
    
    96), mà chúng tôi cần để truy cập thành viên

    scala> import scala.reflect.runtime.{universe => ru}
    import scala.reflect.runtime.{universe=>ru}
    
    scala> val l = List(1,2,3)
    l: List[Int] = List(1, 2, 3)
    
    scala> def getTypeTag[T: ru.TypeTag](obj: T) = ru.typeTag[T]
    getTypeTag: [T](obj: T)(implicit evidence$1: ru.TypeTag[T])ru.TypeTag[T]
    
    scala> val theType = getTypeTag(l).tpe
    theType: ru.Type = List[Int]
    
    4

    Bây giờ chúng ta tra cứu khai báo của trường

    scala> val decls = theType.decls.take(10)
    decls: Iterable[ru.Symbol] = List(constructor List, method companion, method isEmpty, method head, method tail, method ::, method :::, method reverse_:::, method mapConserve, method ++)
    
    95, trường này cung cấp cho chúng ta một
    scala> val decls = theType.decls.take(10)
    decls: Iterable[ru.Symbol] = List(constructor List, method companion, method isEmpty, method head, method tail, method ::, method :::, method reverse_:::, method mapConserve, method ++)
    
    43 (một loại của
    scala> val decls = theType.decls.take(10)
    decls: Iterable[ru.Symbol] = List(constructor List, method companion, method isEmpty, method head, method tail, method ::, method :::, method reverse_:::, method mapConserve, method ++)
    
    44). Chúng tôi sẽ cần sử dụng
    scala> val decls = theType.decls.take(10)
    decls: Iterable[ru.Symbol] = List(constructor List, method companion, method isEmpty, method head, method tail, method ::, method :::, method reverse_:::, method mapConserve, method ++)
    
    44 này sau để có được một bản sao cho phép chúng tôi truy cập vào giá trị của trường này (ví dụ: một số trường hợp)

    scala> import scala.reflect.runtime.{universe => ru}
    import scala.reflect.runtime.{universe=>ru}
    
    scala> val l = List(1,2,3)
    l: List[Int] = List(1, 2, 3)
    
    scala> def getTypeTag[T: ru.TypeTag](obj: T) = ru.typeTag[T]
    getTypeTag: [T](obj: T)(implicit evidence$1: ru.TypeTag[T])ru.TypeTag[T]
    
    scala> val theType = getTypeTag(l).tpe
    theType: ru.Type = List[Int]
    
    9

    Để truy cập thành viên

    scala> val decls = theType.decls.take(10)
    decls: Iterable[ru.Symbol] = List(constructor List, method companion, method isEmpty, method head, method tail, method ::, method :::, method reverse_:::, method mapConserve, method ++)
    
    95 của một phiên bản cụ thể, chúng tôi cần một máy nhân bản cho phiên bản cụ thể của chúng tôi, máy nhân bản của
    scala> val decls = theType.decls.take(10)
    decls: Iterable[ru.Symbol] = List(constructor List, method companion, method isEmpty, method head, method tail, method ::, method :::, method reverse_:::, method mapConserve, method ++)
    
    97,
    scala> val decls = theType.decls.take(10)
    decls: Iterable[ru.Symbol] = List(constructor List, method companion, method isEmpty, method head, method tail, method ::, method :::, method reverse_:::, method mapConserve, method ++)
    
    48. Với gương mẫu của chúng tôi, chúng tôi có thể nhận được một
    scala> val decls = theType.decls.take(10)
    decls: Iterable[ru.Symbol] = List(constructor List, method companion, method isEmpty, method head, method tail, method ::, method :::, method reverse_:::, method mapConserve, method ++)
    
    49 cho bất kỳ
    scala> val decls = theType.decls.take(10)
    decls: Iterable[ru.Symbol] = List(constructor List, method companion, method isEmpty, method head, method tail, method ::, method :::, method reverse_:::, method mapConserve, method ++)
    
    43 nào đại diện cho một trường thuộc loại của
    scala> val decls = theType.decls.take(10)
    decls: Iterable[ru.Symbol] = List(constructor List, method companion, method isEmpty, method head, method tail, method ::, method :::, method reverse_:::, method mapConserve, method ++)
    
    97

    Bây giờ chúng ta có một

    scala> val decls = theType.decls.take(10)
    decls: Iterable[ru.Symbol] = List(constructor List, method companion, method isEmpty, method head, method tail, method ::, method :::, method reverse_:::, method mapConserve, method ++)
    
    49 cho trường cụ thể của mình, chúng ta có thể sử dụng các phương pháp
    scala> val decls = theType.decls.take(10)
    decls: Iterable[ru.Symbol] = List(constructor List, method companion, method isEmpty, method head, method tail, method ::, method :::, method reverse_:::, method mapConserve, method ++)
    
    53 và
    scala> val decls = theType.decls.take(10)
    decls: Iterable[ru.Symbol] = List(constructor List, method companion, method isEmpty, method head, method tail, method ::, method :::, method reverse_:::, method mapConserve, method ++)
    
    54 để lấy/thiết lập thành viên
    scala> val decls = theType.decls.take(10)
    decls: Iterable[ru.Symbol] = List(constructor List, method companion, method isEmpty, method head, method tail, method ::, method :::, method reverse_:::, method mapConserve, method ++)
    
    95 của trường hợp cụ thể của chúng ta. Hãy thay đổi trạng thái của
    scala> val decls = theType.decls.take(10)
    decls: Iterable[ru.Symbol] = List(constructor List, method companion, method isEmpty, method head, method tail, method ::, method :::, method reverse_:::, method mapConserve, method ++)
    
    95 thành
    scala> val decls = theType.decls.take(10)
    decls: Iterable[ru.Symbol] = List(constructor List, method companion, method isEmpty, method head, method tail, method ::, method :::, method reverse_:::, method mapConserve, method ++)
    
    57

    scala> val decls = theType.decls.take(10)
    decls: Iterable[ru.Symbol] = List(constructor List, method companion, method isEmpty, method head, method tail, method ::, method :::, method reverse_:::, method mapConserve, method ++)
    
    0

    Những người cảm thấy thoải mái khi sử dụng phản chiếu Java để lấy các thể hiện của Lớp Java trong thời gian chạy có thể nhận thấy rằng, trong Scala, thay vào đó, chúng tôi lấy các loại thời gian chạy

    REPL-run dưới đây cho thấy một kịch bản rất đơn giản trong đó việc sử dụng phản chiếu Java trên các lớp Scala có thể trả về kết quả đáng ngạc nhiên hoặc không chính xác

    Đầu tiên, chúng ta định nghĩa một lớp cơ sở

    scala> val decls = theType.decls.take(10)
    decls: Iterable[ru.Symbol] = List(constructor List, method companion, method isEmpty, method head, method tail, method ::, method :::, method reverse_:::, method mapConserve, method ++)
    
    58 với một thành viên kiểu trừu tượng là
    scala> case class Person(name: String)
    defined class Person
    
    scala> val m = ru.runtimeMirror(getClass.getClassLoader)
    m: scala.reflect.runtime.universe.Mirror = JavaMirror with ...
    
    5, và từ nó, chúng ta lấy được hai lớp con,
    scala> val decls = theType.decls.take(10)
    decls: Iterable[ru.Symbol] = List(constructor List, method companion, method isEmpty, method head, method tail, method ::, method :::, method reverse_:::, method mapConserve, method ++)
    
    90 và
    scala> val decls = theType.decls.take(10)
    decls: Iterable[ru.Symbol] = List(constructor List, method companion, method isEmpty, method head, method tail, method ::, method :::, method reverse_:::, method mapConserve, method ++)
    
    91

    scala> val decls = theType.decls.take(10)
    decls: Iterable[ru.Symbol] = List(constructor List, method companion, method isEmpty, method head, method tail, method ::, method :::, method reverse_:::, method mapConserve, method ++)
    
    1

    Sau đó, chúng tôi tạo một thể hiện của cả

    scala> val decls = theType.decls.take(10)
    decls: Iterable[ru.Symbol] = List(constructor List, method companion, method isEmpty, method head, method tail, method ::, method :::, method reverse_:::, method mapConserve, method ++)
    
    90 và
    scala> val decls = theType.decls.take(10)
    decls: Iterable[ru.Symbol] = List(constructor List, method companion, method isEmpty, method head, method tail, method ::, method :::, method reverse_:::, method mapConserve, method ++)
    
    91, đồng thời tạo thành phần loại
    scala> case class Person(name: String)
    defined class Person
    
    scala> val m = ru.runtimeMirror(getClass.getClassLoader)
    m: scala.reflect.runtime.universe.Mirror = JavaMirror with ...
    
    5 cụ thể (trong cả hai trường hợp,
    scala> val decls = theType.decls.take(10)
    decls: Iterable[ru.Symbol] = List(constructor List, method companion, method isEmpty, method head, method tail, method ::, method :::, method reverse_:::, method mapConserve, method ++)
    
    95)

    scala> val decls = theType.decls.take(10)
    decls: Iterable[ru.Symbol] = List(constructor List, method companion, method isEmpty, method head, method tail, method ::, method :::, method reverse_:::, method mapConserve, method ++)
    
    2

    Bây giờ, chúng tôi sử dụng các phương thức

    scala> val decls = theType.decls.take(10)
    decls: Iterable[ru.Symbol] = List(constructor List, method companion, method isEmpty, method head, method tail, method ::, method :::, method reverse_:::, method mapConserve, method ++)
    
    96 và
    scala> val decls = theType.decls.take(10)
    decls: Iterable[ru.Symbol] = List(constructor List, method companion, method isEmpty, method head, method tail, method ::, method :::, method reverse_:::, method mapConserve, method ++)
    
    97 từ Java Reflection để lấy một thể hiện của
    scala> val decls = theType.decls.take(10)
    decls: Iterable[ru.Symbol] = List(constructor List, method companion, method isEmpty, method head, method tail, method ::, method :::, method reverse_:::, method mapConserve, method ++)
    
    98 đại diện cho các lớp thời gian chạy của
    scala> val decls = theType.decls.take(10)
    decls: Iterable[ru.Symbol] = List(constructor List, method companion, method isEmpty, method head, method tail, method ::, method :::, method reverse_:::, method mapConserve, method ++)
    
    99 và
    scala> import scala.reflect.runtime.{universe => ru}
    import scala.reflect.runtime.{universe=>ru}
    
    scala> val l = List(1,2,3)
    l: List[Int] = List(1, 2, 3)
    
    scala> def getTypeTag[T: ru.TypeTag](obj: T) = ru.typeTag[T]
    getTypeTag: [T](obj: T)(implicit evidence$1: ru.TypeTag[T])ru.TypeTag[T]
    
    scala> val theType = getTypeTag(l).tpe
    theType: ru.Type = List[Int]
    
    40, sau đó chúng tôi kiểm tra xem lớp thời gian chạy của
    scala> import scala.reflect.runtime.{universe => ru}
    import scala.reflect.runtime.{universe=>ru}
    
    scala> val l = List(1,2,3)
    l: List[Int] = List(1, 2, 3)
    
    scala> def getTypeTag[T: ru.TypeTag](obj: T) = ru.typeTag[T]
    getTypeTag: [T](obj: T)(implicit evidence$1: ru.TypeTag[T])ru.TypeTag[T]
    
    scala> val theType = getTypeTag(l).tpe
    theType: ru.Type = List[Int]
    
    40 có phải là một lớp con của lớp thời gian chạy của
    scala> val decls = theType.decls.take(10)
    decls: Iterable[ru.Symbol] = List(constructor List, method companion, method isEmpty, method head, method tail, method ::, method :::, method reverse_:::, method mapConserve, method ++)
    
    99 không

    scala> val decls = theType.decls.take(10)
    decls: Iterable[ru.Symbol] = List(constructor List, method companion, method isEmpty, method head, method tail, method ::, method :::, method reverse_:::, method mapConserve, method ++)
    
    3

    Vì ở trên, chúng ta đã thấy rằng

    scala> val decls = theType.decls.take(10)
    decls: Iterable[ru.Symbol] = List(constructor List, method companion, method isEmpty, method head, method tail, method ::, method :::, method reverse_:::, method mapConserve, method ++)
    
    91 mở rộng cho
    scala> val decls = theType.decls.take(10)
    decls: Iterable[ru.Symbol] = List(constructor List, method companion, method isEmpty, method head, method tail, method ::, method :::, method reverse_:::, method mapConserve, method ++)
    
    90, kết quả này hơi bất ngờ. Khi thực hiện kiểm tra loại thời gian chạy đơn giản này, người ta sẽ mong đợi kết quả của câu hỏi “Lớp
    scala> import scala.reflect.runtime.{universe => ru}
    import scala.reflect.runtime.{universe=>ru}
    
    scala> val l = List(1,2,3)
    l: List[Int] = List(1, 2, 3)
    
    scala> def getTypeTag[T: ru.TypeTag](obj: T) = ru.typeTag[T]
    getTypeTag: [T](obj: T)(implicit evidence$1: ru.TypeTag[T])ru.TypeTag[T]
    
    scala> val theType = getTypeTag(l).tpe
    theType: ru.Type = List[Int]
    
    40 có phải là lớp con của lớp
    scala> val decls = theType.decls.take(10)
    decls: Iterable[ru.Symbol] = List(constructor List, method companion, method isEmpty, method head, method tail, method ::, method :::, method reverse_:::, method mapConserve, method ++)
    
    99 không?” . Tuy nhiên, như bạn có thể nhận thấy ở trên, khi
    scala> val decls = theType.decls.take(10)
    decls: Iterable[ru.Symbol] = List(constructor List, method companion, method isEmpty, method head, method tail, method ::, method :::, method reverse_:::, method mapConserve, method ++)
    
    99 và
    scala> import scala.reflect.runtime.{universe => ru}
    import scala.reflect.runtime.{universe=>ru}
    
    scala> val l = List(1,2,3)
    l: List[Int] = List(1, 2, 3)
    
    scala> def getTypeTag[T: ru.TypeTag](obj: T) = ru.typeTag[T]
    getTypeTag: [T](obj: T)(implicit evidence$1: ru.TypeTag[T])ru.TypeTag[T]
    
    scala> val theType = getTypeTag(l).tpe
    theType: ru.Type = List[Int]
    
    40 được khởi tạo, trình biên dịch Scala thực sự tạo ra các lớp con ẩn danh của
    scala> val decls = theType.decls.take(10)
    decls: Iterable[ru.Symbol] = List(constructor List, method companion, method isEmpty, method head, method tail, method ::, method :::, method reverse_:::, method mapConserve, method ++)
    
    90 và
    scala> val decls = theType.decls.take(10)
    decls: Iterable[ru.Symbol] = List(constructor List, method companion, method isEmpty, method head, method tail, method ::, method :::, method reverse_:::, method mapConserve, method ++)
    
    91, tương ứng. Điều này là do trình biên dịch Scala phải dịch Scala cụ thể (i. e. , không phải Java) thành một số tính năng tương đương trong mã byte Java để có thể chạy trên JVM. Do đó, trình biên dịch Scala thường tạo các lớp tổng hợp (i. e. các lớp được tạo tự động) được sử dụng trong thời gian chạy thay cho các lớp do người dùng định nghĩa. Điều này khá phổ biến trong Scala và có thể quan sát thấy khi sử dụng phản chiếu Java với một số tính năng của Scala, chẳng hạn như. g. bao đóng, loại thành viên, sàng lọc loại, lớp cục bộ, v.v.

    Trong những tình huống như thế này, thay vào đó, chúng ta có thể sử dụng phản xạ Scala để có được các loại thời gian chạy chính xác của các đối tượng Scala này. Các loại thời gian chạy Scala mang theo tất cả thông tin loại từ thời gian biên dịch, tránh các loại này không khớp giữa thời gian biên dịch và thời gian chạy

    Dưới đây, chúng tôi xác định một phương thức sử dụng phản xạ Scala để lấy các kiểu thời gian chạy của các đối số của nó, sau đó kiểm tra mối quan hệ phân nhóm giữa hai. Nếu kiểu đối số đầu tiên của nó là kiểu con của kiểu đối số thứ hai, thì nó trả về

    scala> val decls = theType.decls.take(10)
    decls: Iterable[ru.Symbol] = List(constructor List, method companion, method isEmpty, method head, method tail, method ::, method :::, method reverse_:::, method mapConserve, method ++)
    
    57

    scala> val decls = theType.decls.take(10)
    decls: Iterable[ru.Symbol] = List(constructor List, method companion, method isEmpty, method head, method tail, method ::, method :::, method reverse_:::, method mapConserve, method ++)
    
    4

    Như chúng ta có thể thấy, bây giờ chúng ta nhận được kết quả như mong đợi– Kiểu thời gian chạy của

    scala> import scala.reflect.runtime.{universe => ru}
    import scala.reflect.runtime.{universe=>ru}
    
    scala> val l = List(1,2,3)
    l: List[Int] = List(1, 2, 3)
    
    scala> def getTypeTag[T: ru.TypeTag](obj: T) = ru.typeTag[T]
    getTypeTag: [T](obj: T)(implicit evidence$1: ru.TypeTag[T])ru.TypeTag[T]
    
    scala> val theType = getTypeTag(l).tpe
    theType: ru.Type = List[Int]
    
    40 thực sự là một kiểu con của kiểu thời gian chạy của
    scala> val decls = theType.decls.take(10)
    decls: Iterable[ru.Symbol] = List(constructor List, method companion, method isEmpty, method head, method tail, method ::, method :::, method reverse_:::, method mapConserve, method ++)
    
    99

    Phản xạ Scala cho phép một dạng siêu lập trình giúp các chương trình có thể tự sửa đổi tại thời điểm biên dịch. Phản ánh thời gian biên dịch này được thực hiện dưới dạng macro, cung cấp khả năng thực thi các phương thức thao tác với cây cú pháp trừu tượng tại thời điểm biên dịch

    Một khía cạnh đặc biệt thú vị của macro là chúng dựa trên cùng một API cũng được sử dụng để phản ánh thời gian chạy của Scala, được cung cấp trong gói

    scala> import scala.reflect.runtime.{universe => ru}
    import scala.reflect.runtime.{universe=>ru}
    
    scala> val l = List(1,2,3)
    l: List[Int] = List(1, 2, 3)
    
    scala> def getTypeTag[T: ru.TypeTag](obj: T) = ru.typeTag[T]
    getTypeTag: [T](obj: T)(implicit evidence$1: ru.TypeTag[T])ru.TypeTag[T]
    
    scala> val theType = getTypeTag(l).tpe
    theType: ru.Type = List[Int]
    
    95. Điều này cho phép chia sẻ mã chung giữa các macro và triển khai sử dụng phản ánh thời gian chạy

    Lưu ý rằng hướng dẫn macro tập trung vào các chi tiết cụ thể của macro, trong khi hướng dẫn này tập trung vào các khía cạnh chung của API phản chiếu. Tuy nhiên, nhiều khái niệm áp dụng trực tiếp cho macro, chẳng hạn như cây cú pháp trừu tượng được thảo luận chi tiết hơn trong phần về Ký hiệu, Cây và Loại

    Môi trường

    Tất cả các nhiệm vụ phản ánh yêu cầu một môi trường thích hợp được thiết lập. Môi trường này khác nhau dựa trên việc tác vụ phản ánh sẽ được thực hiện trong thời gian chạy hay thời gian biên dịch. Sự khác biệt giữa một môi trường được sử dụng trong thời gian chạy hoặc thời gian biên dịch được gói gọn trong cái gọi là vũ trụ. Một khía cạnh quan trọng khác của môi trường phản chiếu là tập hợp các thực thể mà chúng ta có quyền truy cập phản chiếu vào. Tập hợp các thực thể này được xác định bởi cái gọi là gương

    Các gương không chỉ xác định tập hợp các thực thể có thể được truy cập một cách phản chiếu. Họ cũng cung cấp các hoạt động phản ánh được thực hiện trên các thực thể đó. Ví dụ, trong phản ánh thời gian chạy, một gương phản chiếu có thể được sử dụng để gọi một phương thức hoặc hàm tạo của một lớp

    vũ trụ

    scala> import scala.reflect.runtime.{universe => ru}
    import scala.reflect.runtime.{universe=>ru}
    
    scala> val l = List(1,2,3)
    l: List[Int] = List(1, 2, 3)
    
    scala> def getTypeTag[T: ru.TypeTag](obj: T) = ru.typeTag[T]
    getTypeTag: [T](obj: T)(implicit evidence$1: ru.TypeTag[T])ru.TypeTag[T]
    
    scala> val theType = getTypeTag(l).tpe
    theType: ru.Type = List[Int]
    
    96 là điểm vào để phản ánh Scala. Một vũ trụ cung cấp một giao diện cho tất cả các khái niệm chính được sử dụng trong phản ánh, chẳng hạn như
    scala> import scala.reflect.runtime.{universe => ru}
    import scala.reflect.runtime.{universe=>ru}
    
    scala> val l = List(1,2,3)
    l: List[Int] = List(1, 2, 3)
    
    scala> def getTypeTag[T: ru.TypeTag](obj: T) = ru.typeTag[T]
    getTypeTag: [T](obj: T)(implicit evidence$1: ru.TypeTag[T])ru.TypeTag[T]
    
    scala> val theType = getTypeTag(l).tpe
    theType: ru.Type = List[Int]
    
    97,
    scala> import scala.reflect.runtime.{universe => ru}
    import scala.reflect.runtime.{universe=>ru}
    
    scala> val l = List(1,2,3)
    l: List[Int] = List(1, 2, 3)
    
    scala> def getTypeTag[T: ru.TypeTag](obj: T) = ru.typeTag[T]
    getTypeTag: [T](obj: T)(implicit evidence$1: ru.TypeTag[T])ru.TypeTag[T]
    
    scala> val theType = getTypeTag(l).tpe
    theType: ru.Type = List[Int]
    
    98 và
    scala> import scala.reflect.runtime.{universe => ru}
    import scala.reflect.runtime.{universe=>ru}
    
    scala> val l = List(1,2,3)
    l: List[Int] = List(1, 2, 3)
    
    scala> def getTypeTag[T: ru.TypeTag](obj: T) = ru.typeTag[T]
    getTypeTag: [T](obj: T)(implicit evidence$1: ru.TypeTag[T])ru.TypeTag[T]
    
    scala> val theType = getTypeTag(l).tpe
    theType: ru.Type = List[Int]
    
    99. Để biết thêm chi tiết, hãy xem phần của hướng dẫn này về Mirrors hoặc tài liệu API Mirrors trong gói
    scala> import scala.reflect.runtime.{universe => ru}
    import scala.reflect.runtime.{universe=>ru}
    
    scala> val l = List(1,2,3)
    l: List[Int] = List(1, 2, 3)
    
    scala> def getTypeTag[T: ru.TypeTag](obj: T) = ru.typeTag[T]
    getTypeTag: [T](obj: T)(implicit evidence$1: ru.TypeTag[T])ru.TypeTag[T]
    
    scala> val theType = getTypeTag(l).tpe
    theType: ru.Type = List[Int]
    
    95