developer tip

Scala에서 기호를 사용하는 실용적인 예?

copycodes 2020. 11. 28. 09:39
반응형

Scala에서 기호를 사용하는 실용적인 예?


스칼라에는 작은 따옴표 '로 시작하는 이름과 일종의 문자열 상수 인 기호가 있습니다.

루비의 기호를 알고 있습니다 (콜론으로 시작하는 곳). 루비들은 (예를 들어 부재 변수 게터와 세터를 생성하는 것처럼, 몇몇 메타 프로그래밍 작업에 사용되는 attr_reader :name게터 대를 생성 name).

아직 Scala 코드에서 기호를 많이 사용하는 것을 보지 못했습니다. Scala에서 기호의 실제 용도는 무엇입니까?


심볼이 정말 스칼라에 적합합니까?

Lisp의 멋진 땅에서 코드는 자신을 나타내는 리터럴 객체 (문자열, 숫자 등)와 기호의 중첩 된 목록으로 표현되며 클래스, 함수 및 변수와 같은 것에 대한 식별자로 사용됩니다. Lisp 코드는 매우 간단한 구조를 가지고 있기 때문에 Lisp는 프로그래머가이를 조작 할 수 있도록합니다 (컴파일 타임과 런타임 모두). 이 작업을 수행 할 때 프로그래머는 필연적으로 데이터 개체로 기호를 접하게됩니다.

따라서 기호는 어떤 경우에도 Lisp의 객체이며 그럴 필요가 있으므로 해시 테이블 키 또는 열거 형으로도 사용하지 않는 이유는 무엇입니까? 이것은 일을하는 자연스러운 방법이며 특별한 열거 유형을 정의 할 필요가 없기 때문에 언어를 단순하게 유지합니다.

요약하자면 기호는 코드 조작, 열거 및 키잉에 자연스럽게 사용됩니다. 그러나 Java 사람들은 기본적으로 해시 키 간의 동등한 관계로 ID를 사용하지 않으므로 (기존 Lisp가 수행하는 방식) 문자열을 키로 사용할 수 있습니다. Enum 유형은 Scala에서 별도로 정의됩니다. 마지막으로 데이터로서의 코드는 언어에서 전혀 지원되지 않습니다.

그래서 제 인상은 심볼이 스칼라 언어에 속하지 않는다는 것입니다. 즉,이 질문에 대한 답변을 주시하겠습니다. 그것들은 내가 지금 당장 생각할 수없는 스칼라의 진정한 기호 사용을 보여줄 수도 있습니다.

( 부록 : Lisp 방언에 따라 Lisp 기호는 네임 스페이스로 한정 될 수도 있습니다. 이는 물론 코드를 조작 할 때 매우 유용한 기능이고 문자열에는없는 기능입니다.)


웹에서 조금 검색해 보면 스칼라와 같은 언어의 심볼 (기호 리터럴)의 감각은 문자열과 비교하여 의미론의 문제이므로 컴파일러 인식도 가능합니다.

'문자열'은 일련의 문자로 구성된 데이터 유형입니다. 문자열을 조작 할 수 있으므로 조작 할 수 있습니다. 문자열은 파일 이름에서 화면에 인쇄 할 메시지, CSV 파일의 한 줄 등 모든 텍스트 데이터가 의미 상으로 될 수 있습니다.

컴파일러의 경우-따라서 IDE- 문자열은 데이터 유형 String의 값입니다. 숫자 (자릿수 시퀀스)는 Integer와 같은 데이터 유형의 값입니다. 프로그램 수준에서는 "foo"와 "bar"사이에 차이가 없습니다.

OTOH 기호는 프로그램의 항목을 의미 론적으로 식별하는 식별자입니다. 이 문제에서 그것들은 클래스 이름, 메소드 이름 또는 속성 이름과 같습니다. 그러나 클래스 이름은 클래스 (즉, 클래스의 구조와 동작을 선언하는 속성 집합)를 식별하고 메서드 이름은 메서드 (즉, 매개 변수 및 명령문)를 식별하지만 심볼 이름은 기호를 식별합니다. .

따라서 컴파일러는 Foo와 Bar 클래스를 구분하는 것처럼 'foo와'bar '기호를 명시 적으로 구분할 수 있습니다. 컴파일러의 심볼 테이블의 일부로 IDE에서 동일한 메커니즘을 적용 할 수 있습니다. 예를 들어 Foo 클래스의 사용법을 검색하는 것처럼 'foo (즉,이 기호에 대한 참조)의 사용법을 검색 할 수 있습니다.

비교에서 "foo"문자열을 검색하려면 전체 텍스트 스캔과 같은 다른 접근 방식이 필요합니다. 프로그램 코드에서 4711의 모든 항목을 검색하는 것과 동일한 의미를 따릅니다.

그것이 내가 그것을 이해하는 방법이며, 내가 틀렸다면 누군가 나를 고칠 수 있습니다.


Scala 책에 따르면 기호는 인턴됩니다. " 같은 기호를 두 번 쓰면 두 표현식 모두 똑같은 Symbol객체를 참조 합니다. "

대조적으로, Strings는 리터럴 형식으로 나타나는 경우에만 인턴됩니다 (적어도 Java에서는 스칼라에 대해 완전히 확신하지 못함). 따라서 String컬렉션에 넣는 s 의 직렬화를 많이 수행하면 대신 기호를 사용하고 메모리를 절약 할 수 있습니다.

그러나 나는 skaffman에 동의합니다. 나는 그들의 사용에 대해 완전히 확신하지는 않습니다.

(Ruby에서 Symbols는 사용자가 제공하는 메타 프로그래밍 예제와는 별도로 Hashes 에서 키로 자주 사용됩니다 . Ruby에서는 Strings가 인턴되지 않기 때문에 유용합니다 . 모든 사람이 String새 메모리를 할당합니다. Scala에서는 다음과 같이 유용 할 수 있습니다. 나는 당신이 그것을 많은 (비) 직렬화와 결합하면 자바도 String인턴되지 않는다고 언급했다.)


나는 스칼라가 기능적 언어를 사용하기 때문에 추가 한 것 같다.

그러나 그들은 존재의 중심점 인 기호를 통해 식별자를 참조하는 기능을 추가하는 것을 잊었습니다. Scala 2.8에는 그 중 일부를 제공하는 실험적인 기능이 있습니다. API 문서의 관련 부분을 전체적으로 인용하겠습니다.


@experimental

object Invocation 
extends AnyRef

반사 호출을위한보다 편리한 구문입니다. 사용 예 :

    class Obj { private def foo(x: Int, y: String): Long = x + y.length }

다음 두 가지 방법 중 하나로 반사적으로 호출 할 수 있습니다.

    import scala.reflect.Invocation._
    (new Obj) o 'foo(5, "abc")                 // The 'o' method returns Any
    val x: Long = (new Obj) oo 'foo(5, "abc")  // The 'oo' method casts to expected type.

oo메서드 를 호출하고 형식 추론 자에게 충분한 도움을주지 않으면 대부분 추론 Nothing하여 ClassCastException.

저자 Paul Phillips


나는 상징들 간의 비교가 더 빠르다고 믿습니다. Erlang을 사용했다면 메시지를 전달할 때 기호가 톤을 사용하고 저렴하고 빠른 것을 원하며 이는 모든 시스템 경계에서 잘 작동합니다. 나는 Scala, IIRC에 어떤 상태 원격 액터가 있는지 잘 모르겠습니다. 그들은 다소 어리석은 것이었지만, 미래에 그것들이 제자리에있을 때, 심볼은 Erlang에서와 거의 같은 방식으로 매우 유용 할 수 있습니다. 또한 케이스 클래스의 이점 중 일부는 명확하지 않지만 기호는 여전히 저렴합니다.


코드에서 기존 식별자가 아닌 사물의 이름을 참조 할 때 사용한다고 가정합니다. Scala 책은 데이터베이스 열의 이름을 참조하는 예를 제공합니다. 이것은 임의의 문자열이 아니라 실제로 사물의 이름입니다.

그래도 약간 미약하지만 완전히 확신하지는 않습니다.


Scala에서 기호가 실제로 사용되는 경우 한 가지 이름을 지정할 수 있습니다. Play 2.2는 데이터베이스에 접근하기 위해 anorm 을 사용합니다. 다음은 간단한 엔티티 추가 메소드의 코드 샘플입니다.

def add(e:Entity): Option[Long] = {
    DB.withConnection {implicit conn =>
        SQL("insert into ENTITY(name, description) values({name}, {description})").on('name -> e.name, 'description -> e.description).executeInsert()
    }
}

그래서 당신은 .on (bla bla bla)에서 심볼의 사용법을 볼 수 있습니다. 심볼 대신 문자열 리터럴을 사용하는 것도 절대적으로 유효하며 일부 사람들은 그렇게하고 있지만 anorm 소스 코드에서 해당 메서드 서명은 실제로 Symbol 매개 변수를 사용합니다. 유형.


이미 언급했듯이 기호는 다른 (더 많은) 기능 언어에서 이월됩니다. 다른 사람들이 언급하지 않은 것은 그들이 기호의 역할을 채울뿐만 아니라 키워드와 가장 가까운 동등 물이기도합니다 (성능 이점을 뺀 것입니다). 제 생각에는 명시 적 식별자를 의미하는 키워드로 더 유용합니다.

Below I will include a court description from Clojure docs of keywords and symbols.

Symbols

Symbols are identifiers that are normally used to refer to something else. They can be used in program forms to refer to function parameters, let bindings, class names and global vars. They have names and optional namespaces, both of which are strings. Symbols can have metadata (see with-meta).

Keywords

Keywords are symbolic identifiers that evaluate to themselves. They provide very fast equality tests. Like Symbols, they have names and optional namespaces, both of which are strings. The leading ':' is not part of the namespace or name.

Scala symbols are not as powerful as symbols in some languages. Therefore, they are not as useful either. However, I don't see why they couldn't offer the same meta-programming and performance advantages as keywords. At the very least, they can make your code easier to read.

참고URL : https://stackoverflow.com/questions/1324466/practical-examples-of-using-symbols-in-scala

반응형