Scala에서 구문 설탕의 모든 인스턴스는 무엇입니까?
Scala에서 구문 설탕의 모든 인스턴스는 무엇입니까?
대부분 / 모두가 순전히 기호이므로 개념의 이름을 모르면 검색하기 어렵 기 때문에 검색하기가 어렵습니다.
할 것:
- 암시 적 변환
_
익명 함수 구문- 내가 잊고있는 다른 것들
기초:
a b
다음과 같다a.b
a b c
로 끝나는a.b(c)
경우를 제외 하고는와 동일합니다 . 이 경우 다음과 같습니다.b
:
a b c
c.b(a)
a(b)
동등a.apply(b)
이것은 익명 함수에 대한 다음의 정의는 동일 이유 : 브로 square1 = (X : INT) => X X 발 square2 = 새로운 기능 1 [INT, 지능 {DEF 적용 (X : INT) = X X}호출 할 때
square1(y)
, 당신은 실제로 호출square1.apply(y)
하는square1
으로로 지정해야합니다Function1
(또는 특성Function2
... 등)a(b) = c
는a.update(b,c)
Likewise 와 동일하며 ,a(b,c) = d
등가a.update(b,c,d)
입니다.a.b = c
와 동일합니다a.b_=(c)
. 당신이 만들 때val
/를var
x
클래스 / 객체에, 스칼라는 방법을 생성x
하고x_=
당신을 위해입니다. 당신이 자신을 정의 할 수 있습니다,하지만 당신은 정의하면y_=
당신이 있어야 정의y
, 또는 예를 들어, 컴파일되지 않습니다scala> val b = new Object{ def set_=(a: Int) = println(a) } b: java.lang.Object{def set_=(Int): Unit} = $anon$1@17e4cec scala> b.set = 5 <console>:6: error: value set is not a member of java.lang.Object{def set_=(Int): Unit} b.set = 5 ^ scala> val c = new Object{ def set = 0 ; def set_=(a:Int) = println(a) } c: java.lang.Object{def set: Int; def set_=(Int): Unit} = $anon$1@95a253 scala> c.set = 5 5
-a
에 대응a.unary_-
마찬가지로 대+a
,~a
및!a
a <operator>= b
, 여기서는<operator>
일부 특수 문자 집합은 메서드 가없는 경우a = a <operator> b
에만 동일합니다. 예를 들어,a
<operator>=
class test(val x:Int) { def %%(y: Int) = new test(x*y) } var a = new test(10) a.x // 10 a %%= 5 //Equivalent to a = a %% 5 a.x // 50
Jaxkson의 답변 외에도 :
type F[A,B]
로 사용할 수 있습니다A F B
.
예를 들면 :
type ->[A,B] = (A,B)
def foo(f: String -> String)
- 사용
=> type
방법 정의에하는 함수 썽크에서 메서드 호출 내부 컴파일러 랩 표현한다.
예를 들면
def until(cond: => Boolean)(body: => Unit) = while(!cond) body
var a = 0
until (a > 5) {a += 1}
특수 클래스 : 튜플 및 기호
Rahul G가 언급했듯이 튜플과 기호는 약간 특별한 구문을 얻습니다.
- 기호 : 구문
'x
은Symbol("x")
- 튜플 :
(p1,p2,..,pn)
케이스 클래스의 줄임말Tuplen[T1,T2,..,Tn](p1,p2,..,pn)
예를 들어, 다음 두 가지는 동일합니다.
val tuple1 = ("Hello",1)
val tuple2 = Tuple2[String,Int]("Hello",1)
추출기 :
이 추출기에 사용되는 두 가지 방법이 있습니다, unapply
그리고 unapplySeq
. 이들은 여러 변수 할당 및 패턴 일치에 사용됩니다.
첫 번째 사용 사례는 unapply가 일치해야하는 개체를 가져와 일치
Boolean
하는지 여부에 따라를 반환하는 경우입니다. 예를 들어,trait Gender trait Male extends Gender trait Female extends Gender object Male extends Male object Female extends Female class Person(val g: Gender, val age: Int) object Adult { def unapply(p: Person) = p.age >= 18 } def check(p: Person) = p match { case Adult() => println("An Adult") case _ => println("A Child") } //Will print: An Adult since Adult.unapply returns true. check(new Person(Female, 18)) //Will print: A Child as it falls through to the _ case. check(new Person(Male, 17))
Honestly, I don't really get the purpose of the above syntax since it can be done almost just as easily by just putting the code in the case
statements. Of course if you have a better example, leave a comment below
The general case where
unapply
takes some fixed-number of parameters and returns either anOption[T]
for a single parameter or aOption[(p1,p2,...)]
for multiple, i.e. a Tuple with the matched values, for example, continuing from the above code:object Person { def apply(g: Gender, age: Int) = new Person(g, age) def unapply(p: Person) = if(p.age < 0) None else Some((p.g, p.age)) } //Using Person.apply as described in the Basics section val alice = Person(Female, 30) val bob = Person(Male, 25) //This calls Person.unapply(alice), which returns Some((Female, 30)). //alice_gender is assigned Female and alice_age 30. val Person(alice_gender, alice_age) = alice bob match { //Calls Person.unapply(bob), but sees that g is Male, so no match. case Person(Female, _) => println("Hello ma'am") //Calls Person.unapply(bob) and assigns age = bob.age, but it doesn't pass //the 'if' statement, so it doesn't match here either. case Person(Male, age) if age < 18 => println("Hey dude") //So bob falls through to here case _ => println("Hello Sir") } Person(Male,-1) match { //Person.unapply(Person.apply(Male,-1)) returns None because p.age < 0. //Therefore this case will not match. case Person(_, _) => println("Hello person") //Thus it falls through to here. case _ => println("Are you Human?") }
Note: Case classes do all those apply
/unapply
definitions for you (as well as other stuff) so use them whenver possible to save time and reduce code.
unapplySeq
. This works similarly tounapply
as above, except it must return anOption
of some kind of sequence.
As a quick example,
scala> List.unapplySeq(List(1,2,3))
res2: Some[List[Int]] = Some(List(1, 2, 3))
Anonymous functions:
_ + _
is short for (a, b) => a + b
Context bounds desugar into implicit
parameters, e.g. consider a function that leverages the Monoid
type class:
def suml[T: Monoid](xs: List[T]) = {
val T = implicitly[Monoid[T]]
xs.foldLeft(T.mzero)(T.mplus)
}
where the : Monoid
part is a context bound, gets translated to:
def suml[T](xs: List[T])(implicit evidence$1: Monoid[T]]) = {
...
}
therefore the following compiles, too:
def suml[T: Monoid](xs: List[T]) = {
val T = evidence$1
...
}
참고URL : https://stackoverflow.com/questions/2662984/what-are-all-the-instances-of-syntactic-sugar-in-scala
'Program Tip' 카테고리의 다른 글
WPF의 코드 숨김을 통해 리소스에 액세스 (0) | 2020.11.27 |
---|---|
Perl의 배열에 정규식 캡처를 어떻게 저장할 수 있습니까? (0) | 2020.11.27 |
이 사용자가 익명인지 또는 실제로 내 시스템의 사용자인지 어떻게 확인합니까? (0) | 2020.11.27 |
Java에서 소수점 이하 두 자리로 반올림하는 방법은 무엇입니까? (0) | 2020.11.27 |
목록 항목을 열로 표시하는 방법은 무엇입니까? (0) | 2020.11.27 |