[解決済み] と()=>、Unit=>の違いは何ですか?
質問
引数を取らず、値を返さない関数を表現しようとしています(JavaScriptのsetTimeout関数をシミュレートしています。)
case class Scheduled(time : Int, callback : => Unit)
は、 " `val' パラメータは call-by-name でない可能性があります" と言って、コンパイルされません。
case class Scheduled(time : Int, callback : () => Unit)
はコンパイルされますが、変に起動する必要があります。
Scheduled(40, { println("x") } )
私はこれをしなければならない
Scheduled(40, { () => println("x") } )
また、次のようなものもあります。
class Scheduled(time : Int, callback : Unit => Unit)
が、さらに意味不明な方法で呼び出されます。
Scheduled(40, { x : Unit => println("x") } )
(Unit型の変数は何になるのか?)私の場合 欲しい もちろん、普通の関数と同じように呼び出すことができるコンストラクタが必要です。
Scheduled(40, println("x") )
赤ちゃんに哺乳瓶をあげよう
解決方法は?
コール・バイ・ネーム:=> タイプ
は
=> Type
という表記はコール・バイ・ネームの略であり、これは
いろいろな方法
パラメータを渡すことができます。今はcall-by-valueやcall-by-referenceが主流ですが、もし馴染みがなければ、そのwikipediaの記事を時間をかけて読んでみることをお勧めします。
どういうことかというと、渡されるものは 代入 を関数内の値名として使用します。例えば、こんな関数がある。
def f(x: => Int) = x * x
このように呼び出すと
var y = 0
f { y += 1; y }
すると、コードは次のように実行されます。
{ y += 1; y } * { y += 1; y }
しかし、その場合、識別子の名前がぶつかったらどうするのか、という問題が出てきます。従来の call-by-name では、名前の衝突を避けるために capture-avoiding substitution と呼ばれるメカニズムが働きます。しかし Scala では、これは別の方法で実装されており、結果は同じです。パラメータ内の識別子名は、呼び出される関数内の識別子を参照したり、シャドウしたりすることはできません。
call-by-nameについては、他にもいくつかポイントがあるので、他の2つを説明した後にお話しします。
0-arity関数。() => タイプ
構文
() => Type
の型を表します。
Function0
. つまり、パラメータを取らず、何かを返す関数です。これは、例えば、メソッド
size()
-- パラメータを取らず、数値を返す。
しかし、この構文が 無名関数リテラル これが混乱の原因になっている。例えば
() => println("I'm an anonymous function")
はアリティ 0 の無名関数リテラルで、その タイプ は
() => Unit
だから、書けるんです。
val f: () => Unit = () => println("I'm an anonymous function")
ただし、型と値を混同しないようにすることが重要です。
単位 => タイプ
これは実際には単なる
Function1
で、その最初のパラメータは
Unit
. 他の書き方としては、以下のようになります。
(Unit) => Type
または
Function1[Unit, Type]
. しかし......これでは、人が望んでいるものになることはまずないでしょう。その
Unit
型の主な目的は、興味のない値を示すことです。
受け取る
という値です。
例えば、考えてみてください。
def f(x: Unit) = ...
で何ができるのでしょうか?
x
? それは単一の値しか持つことができないので、それを受け取る必要はありません。一つの可能な使い方は
Unit
:
val f = (x: Unit) => println("I'm f")
val g = (x: Unit) => println("I'm g")
val h = f andThen g
なぜなら
andThen
にのみ定義されます。
Function1
を返し、連鎖している関数は
Unit
の型であると定義する必要がありました。
Function1[Unit, Unit]
を連鎖させることができます。
混乱の元となるもの
最初の混乱の原因は、0-arity関数に存在する型とリテラルの類似性が、call-by-nameにも存在すると考えることです。言い換えれば、以下のように考えてしまうことです。
() => { println("Hi!") }
はリテラルで
() => Unit
であれば
{ println("Hi!") }
はリテラルで
=> Unit
. そうではありません。それは
ブロックコード
は、リテラルではありません。
もう一つの混乱の原因は
Unit
型の
値
が書かれています。
()
これは,0-arityのパラメータリストのように見えます(しかし,そうではありません).
関連
-
[解決済み] ScalaのSeqとListの違いについて
-
[解決済み] Scalaのオブジェクトとクラスの違い
-
[解決済み] Scalaのcase classとclassの違いは何ですか?
-
[解決済み] self-typesとtrait subclassの違いは何ですか?
-
[解決済み】Scalaにおける中括弧と括弧の正式な違い、また、どのような場合に使用すべきなのか?
-
[解決済み】Scalaのvarとvalの定義の違いは何ですか?
-
[解決済み】case objectとobjectの違いについて
-
[解決済み】Scala 2.8 breakOut
-
[解決済み] 縮小、折りたたみ、スキャン(左/右)?
-
[解決済み] Scalaの==と.equalsの違いは何ですか?
最新
-
nginxです。[emerg] 0.0.0.0:80 への bind() に失敗しました (98: アドレスは既に使用中です)
-
htmlページでギリシャ文字を使うには
-
ピュアhtml+cssでの要素読み込み効果
-
純粋なhtml + cssで五輪を実現するサンプルコード
-
ナビゲーションバー・ドロップダウンメニューのHTML+CSSサンプルコード
-
タイピング効果を実現するピュアhtml+css
-
htmlの選択ボックスのプレースホルダー作成に関する質問
-
html css3 伸縮しない 画像表示効果
-
トップナビゲーションバーメニュー作成用HTML+CSS
-
html+css 実装 サイバーパンク風ボタン
おすすめ
-
[解決済み] Scalaでswitch/case(単純なパターンマッチ)を使うには?
-
[解決済み] Scalaで定期的に関数を実行する
-
[解決済み] データフレームを複数回グループ化する
-
[解決済み] Scala vs. Groovy vs. Clojure [終了しました]。
-
[解決済み】Scalaの記号演算子にはどんな意味があるの?
-
[解決済み】良いスカラズの紹介【終了しました
-
[解決済み】Scalaで変数をキャストする方法は?
-
[解決済み] 型の論理和(ユニオン型)はどのように定義するのですか?
-
[解決済み] 2つのマップをマージし、同じキーの値を合計するための最良の方法?
-
[解決済み] Scalaで環境変数を読み込む方法