學習 scala 的第 1 天:
這是我的代碼,但在一種情況下我得到了意想不到的結果。
object Hello extends App {
def square(x: Int) = x * x
println("Hello, World!")
}
object main extends App {
println(Hello.square(2))
}
那么輸出是(正確的)
4
但是當我在沒有 Hello 擴展 App 的情況下運行 main 時,
object Hello {
def square(x: Int) = x * x
println("Hello, World!")
}
object main extends App {
println(Hello.square(2))
}
我明白了。
Hello, World!
4
怎么了?當我簡單地呼叫 Hello.square 函式時,為什么 main 會執行 Hello 物件中的所有內容?
uj5u.com熱心網友回復:
使用 anObject本質上是使用靜態類,因此在構造物件時會評估其中的所有代碼。println因此,實際上,無論您是否在物件上呼叫某些東西,預期的結果都會發生。
那么問題是,你怎么看不到這種行為
object Hello extends App {
def square(x: Int) = x * x
println("Hello, World!")
}
好吧,唯一的區別是extends App確實在我們可以看到的檔案中
注意事項
應該注意的是,這個 trait 是使用 DelayedInit功能實作的,這意味著物件的欄位在 main 方法執行之前不會被初始化。
因此,當您的第一個實作建立在 App 實作的限制之上時 - 這可能會改變為
此特征的未來版本將不再擴展 DelayedInit。
最好將任何“免費”代碼放在 Hello 內部函式中,以防止您看到意外的副作用
uj5u.com熱心網友回復:
我的理解是,當您參考物件時,物件塊中的所有內容都會被評估。和
object Hello {
def square(x: Int) = x * x
println("Hello, World!")
}
表現得像
object Hello {
def square(x: Int) = x * x
val _ = println("Hello, World!")
}
因為println()會產生副作用并回傳Unit/ (),在這種情況下會立即丟棄。所以列印只是評估物件時產生的副作用。另請注意以下示例:
object Hello {
def square(x: Int) = x * x
println("Hello, World!")
}
object main extends App {
println("first")
Hello
println("second")
println(Hello.square(2))
println("third")
}
這列印
first
Hello, World!
second
4
third
所以 hello world 的列印只發生一次,它在Hello被參考時發生,而不是在square()被呼叫時發生。
通常,您不希望有在物件中產生副作用的代碼。這更像是函式和值/變數的地方。例如:
object Hello {
val w = "World"
def greet(what: String): Unit = println(s"Hello, $what!")
}
object main extends App {
Hello.greet(Hello.w)
Hello.greet("Scala")
}
或者,如果您希望該值是動態的,則可以改用一個類:
class Hello(val w: String) {
def greet(what: String): Unit = println(s"Hello, $what!")
}
object main extends App {
val h = Hello("World")
h.greet(h.w)
h.greet("Scala")
}
編輯:更改了初始答案的一些不正確的細節。
轉載請註明出處,本文鏈接:https://www.uj5u.com/yidong/447283.html
