program story

Scala에서 메소드를 정의하는 9 가지 방법?

inputbox 2020. 12. 9. 08:09
반응형

Scala에서 메소드를 정의하는 9 가지 방법?


그래서 저는 Scala에서 물건을 정의 할 수있는 다양한 방법을 이해하려고 노력했습니다. {}블록이 처리 되는 방식에 대한 이해 부족으로 복잡합니다 .

object NewMain extends Thing{

    def f1 = 10
    def f2 {10}
    def f3 = {10}
    def f4() = 10
    def f5() {10}
    def f6() = {10}
    def f7 = () => 10
    def f8 = () => {10}
    def f9 = {() => {10}}

    def main(args: Array[String]){
        println(f1)     // 10
        println(f2)     // ()
        println(f3)     // 10
        println(f4)     // 10
        println(f4())   // 10
        println(f5)     // ()
        println(f5())   // ()
        println(f6)     // 10
        println(f6())   // 10
        println(f7)     // <function0>
        println(f7())   // 10
        println(f8)     // <function0>
        println(f8())   // 10
        println(f9)     // <function0>
        println(f9())   // 10
    }

}

아마도 이것들 중 일부는 동등하고, 일부는 다른 것의 구문 적 설탕이며, 일부는 내가 사용하지 말아야 할 것들이지만, 나는 그것을 알아낼 수 없습니다. 내 구체적인 질문은 다음과 같습니다.

  • 어떻게 것입니다 println(f2)println(f5())제공 unit? 블록의 마지막 항목이 10아닙니까? 어떻게 다른 println(f3())주는, 10?

  • 경우 println(f5)제공 unit, 안 println(f5())하기 때문에, 무효 unit함수 아닌가요? 같은가 적용 println(f6)하고println(f6())

  • : 10 인쇄 모든 사람의 f1, f3, f4, f4(), f6, f6(), f7(), f8(), f9(), (내가 사용하는시기의 측면에서) 또는 사용의 차이 (그것이 무엇의 측면에서) 그들 사이의 기능적 차이가? 아니면 모두 동등합니까?


질문에 순서대로 답변하려면 :

  • f2f5()반환 Unit스칼라 어떤 걸리기 때문에 def하지 않고 "는 ="함수가 될 것을 반환 Unit에 관계없이 블록에서 마지막 항목이 무엇인지. 그렇지 않으면 아무것도 반환하지 않는 함수를 정의하는 것이 다소 장황하지 않기 때문에 이것은 좋은 것입니다.
  • println(f5())Unit스칼라 Unit에서 유효한 객체 이기 때문에 반환하더라도 유효하지만 인스턴스화 할 수있는 것은 아닙니다. Unit.toString()예를 들어 일반적으로 유용하지는 않지만 유효한 진술입니다.
  • 인쇄되는 모든 버전이 10동일 하지는 않습니다 . 가장 중요한 것은 f7, f8f9반환 함수는 반환한다는 것을 기능을 실제로 10보다는 반환 10직접적으로는. 를 선언하면 인수가없는 def f8 = () => {10}함수 f8선언하고 인수를받지 않고 단일 정수를 반환하는 함수를 반환합니다. 호출 println(f8)하면 f8부지런히 그 함수를 반환합니다. 호출 println(f8())하면 함수가 반환되고 즉시 호출됩니다.
  • 기능은 f1, f3, f4, 그리고 f6모든 본질적으로 동등한 그들이 무엇의 관점에서, 그들은 스타일의 측면에서만 다릅니다.

"사용자 알 수 없음"에서 알 수 있듯이 중괄호는 범위 지정 목적으로 만 중요하며 여기에서 사용 사례에 차이를 만들지 않습니다.


def f() {...}

에 대한 구문 설탕입니다

def f(): Unit = {...}

따라서 "="를 생략하면 메서드는 항상 Unit 유형의 객체를 반환합니다. Scala에서 메서드와 표현식은 항상 무언가를 반환합니다.

def f() = 10
is sytactic sugar for
def f() = {
10
}

def f () = () => 10이라고 쓰면 쓰는 것과 같습니다.

def f() = {
() => 10
}

즉, f는 함수 객체를 반환합니다. 그러나 당신은 쓸 수 있습니다

val f = () => 10

f ()를 사용하여 호출하면 10 개의 Function 객체를 반환하고 대부분의 경우 메서드를 교대로 사용할 수 있지만 몇 가지 구문 차이가 있습니다. 예를 들어 쓸 때

def f() = 10
println(f)

당신은 "10"을 얻지 만 당신이 쓸 때

val f = () => 10
println(f)

당신은 얻을

<function0>

On the other hand when you have this

val list = List(1,2,3)
def inc(x: Int) = x+1
val inc2 = (x: Int) => x+1
println(list.map(inc))
println(list.map(inc2))

Both println will print the same thing

List(2,3,4)

When you use the name of a method at a place where a function object is expected and the method signature matches the signature of the expected function object it is automatically converted. So list.map(inc) gets automatically converted by the scala compiler into

list.map(x => inc(x))

Six years later, in a future version of Scala to be released even further in the future, things have improved:

That brings our 9 ways of defining a function and 15 ways of calling them down to 7 ways of defining a function and 10 ways of calling them:

object NewMain extends Thing{

    def f1 = 10
    def f3 = {10}
    def f4() = 10
    def f6() = {10}
    def f7 = () => 10
    def f8 = () => {10}
    def f9 = {() => {10}}

    def main(args: Array[String]){
        println(f1)     // 10
        println(f3)     // 10
        println(f4())   // 10
        println(f6())   // 10
        println(f7)     // <function0>
        println(f7())   // 10
        println(f8)     // <function0>
        println(f8())   // 10
        println(f9)     // <function0>
        println(f9())   // 10
    }
}

See also lampepfl/dotty2570 lampepfl/dotty#2571

As a result, it's relatively clear which syntax is optional (e.g. {}s) and which definitions are equivalent (e.g. def f4() = 10 and def f7 = () => 10). Hopefully, some day when Dotty/Scala-3.0 is released, newbies learning the language will no longer face the same confusion I did six years ago.


def f1 = 10    
def f2 {10}    

The second form does not use an assignment. Therefore you can think of it as an Procedure. It is not meant to return something, and returns therefore Unit, even if the last statement could be used to return something specific (but it could be an if-statement, which would only have something specific in one branch).

def f1 = 10    
def f3 = {10}  

You don't need braces here. You need them, for instance, if you define a val, so the scope of this val is restricted to the enclosing block.

def sqrGtX (n:Int, x: Int) = {
  val sqr = n * n
  if (sqr > x) 
    sqr / 2 
  else x / 2 
}  

You need the curly braces to define val sqr here. If the val is declared in an inner branch, the curly braces don't need to be at the top-level of the method:

def foo (n:Int, x: Int) = 
  if (n > x) {
    val bar = x * x + n * n
    println (bar) 
    bar - 2  
  } else x - 2 

For further investigation when two methods return the same result, you can compile them and compare the bytecode. Two binary identical methods will be identic.

참고URL : https://stackoverflow.com/questions/8303817/nine-ways-to-define-a-method-in-scala

반응형