これが Scala の真髄です。これを受講すれば、面接を恐れることはありません。

これが Scala の真髄です。これを受講すれば、面接を恐れることはありません。

[[427956]]

この記事はWeChatの公開アカウント「ビッグデータ左右手」から転載したもので、著者はZuoyouです。この記事を転載する場合は、Big Data Left and Right Hand の公開アカウントにご連絡ください。

序文

オブジェクト指向の関数型プログラミング言語である Scala は、オブジェクト指向プログラミングと関数型プログラミングを組み合わせて、コードをより簡潔で効率的かつ理解しやすいものにします。これが Scala が人気を博した理由です。

Scala は JVM 言語です。ビッグデータ エコシステムのほとんどのコンポーネントは Java で開発されており、Scala は Java とシームレスに混合できるため、ビッグデータ エコシステムにうまく統合できます。

メインコンテンツ

開発環境、ループ、例外、ジェネリックなどの基本的なものは記載されなくなります。この記事では、概念の理解と使用方法に重点を置いて、独自の特別なエッセンスのみを紹介します。

1. 変数とデータ型

2. 関数型プログラミング

(a) 高階関数

(b) 匿名関数

(c)閉鎖

(d) 関数カリー化

3. オブジェクト指向

(a) クラスとオブジェクト

(b) コンパニオンオブジェクト

(c)特徴

4. パターンマッチング

5. 暗黙的な変換

変数とデータ型

変数(var は変数を宣言し、val は定数を宣言します)

var修飾子変数は変更可能です

val によって変更された変数は変更できません

しかし、本当にそうなのでしょうか?

以下の定義について

  1. クラスA(a: Int ) {
  2. var 値 = a
  3. }
  4.  
  5. クラスB(b: Int ) {
  6. val値 = 新しいA(b)
  7. }

効果テスト

  1. val x = 新しいB(1)
  2.  
  3. x = new B(1) // エラー。x は val によって変更されており、参照は変更できないため
  4. x.value = new A(1) // エラー。x.value は val によって変更されており、参照は変更できないため
  5.  
  6. x.value.value = 1 // 正解、x.value.valueはvarによって変更され、再割り当てできます

実際、var によって変更されたオブジェクト参照は変更できますが、val によって変更されたオブジェクト参照は変更できませんが、オブジェクトの状態は変更できます。

可変性と不変性の理解

Scala の List は不変であり、Map は可変と不変の両方であることがわかっています。次の例を見てください

var mutable と List immutable の組み合わせ

  1. var list = List( "左" , "右" )
  2.  
  3. リスト += "手"  

理解とは

var list が指すオブジェクトは List("left","right") です。

後でリストが変更されます。変数var修飾子なので、リストは新しいリスト(「left」、「right」、「hand」)を指すことができます。

以下の場合(エラーを報告します)

  1. val list = List( "左" , "右" )
  2.  
  3. リスト += "手"  

val var と Map の可変と不変

  1. var map = マップ(
  2. 「左」 -> 1、
  3. 「右」 ->1、
  4. map+=( "手" ->1)
  1. val map=scala.collection.mutable.Map(
  2. 「左」 -> 1、
  3. 「右」 ->1、
  4.  
  5. map+=( "手" ->1)

理解する

不変のマップに要素を追加すると、元のマップは変更されず、元のマップと追加された要素を保存するために新しいマップが生成されます。

変更可能なマップに要素を追加する場合、新しいマップは生成されず、要素は元のマップに直接追加されます。

val に関して不変なのはポインターのみであり、これはオブジェクト マップとは関係ありません。

データ型

データ型説明する
バイト 8 ビットの符号付き 2 の補数整数。値の範囲は-128~127です
短い 16 ビットの符号付き 2 の補数整数。値の範囲は-32768~32767です
中級 32 ビットの符号付き 2 の補数整数。値の範囲は -2147483648 ~ 2147483647 です
長さ 64 ビットの符号付き 2 の補数整数。値の範囲は -9223372036854775808 から 9223372036854775807 です。
フロート 32 ビット、IEEE 754 標準単精度浮動小数点数
ダブル 64 ビット IEEE 754 標準倍精度浮動小数点数
チャー 16 ビットの符号なし Unicode 文字、範囲の値は U+0000 から U+FFFF です。
文字列
ブール真実か偽か
ユニット値がないことを表します。他の言語の void に相当します。結果を返さないメソッドの結果タイプとして使用されます。ユニットには、() として記述されるインスタンス値が 1 つだけあります。
ヌル null または空の参照
何もない Nothing 型は Scala のクラス階層の最下部にあります。それは他のすべてのタイプのサブタイプです。
どれでも Anyは他のすべてのクラスのスーパークラスです
任意の参照 AnyRef クラスは、Scala のすべての参照クラスの基本クラスです。

関数型プログラミング

高階関数

高階関数とは、他の関数をパラメータとして受け取ったり、結果として関数を返したりする関数です。関数は Scala の第一級オブジェクトです。

簡単な例

  1. val リスト = リスト (1,2,3,4)
  2.  
  3. val関数= (x: Int ) => x*2
  4.  
  5. val 値=list.map(関数)

関数としてのメソッド

  1. def main(args: Array[String]): 単位 = {
  2. val リスト = リスト (1,2,3,4)
  3. val 値=list.map(関数)
  4. }
  5.  
  6. def関数(x: Int )=x*2

関数を返す関数

  1. def calculate(シンボル:文字列): (文字列,文字列)=>文字列 ={
  2. シンボルマッチ {
  3. 場合  "スプライシング方法 1" => (a:String,b:String)=> s "スプライシング方法 1:$a,$b"  
  4. 場合  「連結方法 2」 => (a:String,b:String)=> s 「連結方法 2: $b 、 $a」  
  5. }
  6. }
  1. val関数: (String, String) => String = calculate( "スプライシング方法 2" )
  2.  
  3. println(関数( "ビッグデータ" "左手と右手" ))

匿名関数

Scala で匿名関数を定義する構文は非常にシンプルで、矢印の左側にパラメータ リスト、右側に関数本体が配置されます。

匿名関数を使用すると、コードはより簡潔になります。

  1. var inc = (x: Int ) => x+1 です。
  2.  
  3. var x = inc(7)-1

パラメータなしも可能

  1. var user = () => println( "ビッグデータの右手" )

閉鎖

クロージャは、戻り値が関数外で宣言された 1 つ以上の変数に依存する関数です。

クロージャは一般に、関数内のローカル変数にアクセスできる別の関数と考えることができます。

簡単に言えば、関数内の変数がそのスコープ内にない場合でも、外部からアクセスできるということです。

  1. val関数= (x: Int ) => x*2

クロージャの本質は、コードと非ローカル変数の混合である。

クロージャ = コード + 使用される非ローカル変数

  1. val 事実 = 2
  2. val関数= (x: Int ) => x*fact

関数カリー化

カリー化とは、もともと 2 つのパラメータを受け入れる関数を、 1 つのパラメータを受け入れる新しい関数に変換するプロセスを指します。新しい関数は、元の 2 番目の引数を引数として受け取る関数を返します。

まず簡単な

  1. def add (x: Int ,y: Int )=x+y
  2.  
  3. 使用
  4.  
  5. (1,2)を加える

関数変換(この方法はカリー化と呼ばれます)

  1. def add (x: Int ,y: Int )=x+y
  2.  
  3. 使用
  4.  
  5. (1,2)を加える

実装プロセス

add(1)(2)は実際には2つの通常の関数(非カリー化関数)を順番に呼び出します。

最初の呼び出しは 1 つの引数 x を受け取り、関数型の値を返します。

2 回目にこの関数が呼び出されるときは、パラメータ y の値が使用されます。

  1. xをパラメータとして受け取り、無名関数を返す
  2.  
  3. Intパラメータ y を受け取り、関数本体は x+y です。
  4.  
  5. def add (x: Int )=(y: Int )=>x+y
  6.  
  7. (1)
  8. val result = add (1) // 結果= (y: Int )=>1+y
  9.  
  10. (2)
  11. val合計= 結果(2)
  12.  
  13. (3)
  14. 合計= 3

オブジェクト指向

クラスとオブジェクト

クラスはオブジェクトの抽象化であり、オブジェクトはクラスの具体的なインスタンスです。クラスは抽象的でありメモリを占有しませんが、オブジェクトは具体的でありストレージスペースを占有します。クラスはオブジェクトを作成するための設計図です。特定のタイプのオブジェクトに含まれるメソッドと変数を定義するソフトウェア テンプレートです。

クラスにはクラスパラメータがある

クラス パラメータはクラスの本体内で直接使用できます。クラス パラメータには var というプレフィックスを付けることもでき、private、protected、override を使用して変更することもできます。 Scala コンパイラはクラス パラメータを収集し、同じパラメータを持つクラスのプライマリ コンストラクターを作成します。 、フィールドでもメソッド定義でもないクラス内のすべてのコードをプライマリ コンストラクターにコンパイルします。

  1. クラスTest(val a: Int , val b: Int ) {
  2. //
  3. }

例クラス

ケース クラスは通常、パターン マッチング用に最適化できる特別なクラスであるサンプル クラスに変換されます。

クラスがケースクラスとして宣言されている場合。以下の機能があります:

  1. コンストラクター内のパラメーターが var として宣言されていない場合は、デフォルトで val 型になります。
  2. コンパニオン オブジェクトを自動的に作成し、その中にサブ適用メソッドを実装して、使用時に new を使用してオブジェクトを直接作成する必要がないようにしました。
  3. コンパニオン オブジェクトは、ケース クラスをパターン マッチングに適用できるように、unapply メソッドを実装するのにも役立ちます。
  4. 独自のtoString、hashCode、copy、equalsメソッドを実装する
  1. ケースクラス人(
  2. 名前:文字列、
  3. 年齢: 

オブジェクトとコンパニオンオブジェクト

Scala シングルトン オブジェクトは非常に重要です。 Java とは異なり、静的クラス、静的メンバー、静的メソッドはありませんが、Scala はオブジェクト オブジェクトを提供します。このオブジェクトは Java の静的クラスに似ています。デフォルトでは、そのメンバーとメソッドは静的です。

シングルトン オブジェクトを定義することはクラスを定義することを意味しないため、それを使用して新しいオブジェクトを作成することはできません。シングルトン オブジェクトがクラスと同じ名前を共有する場合、そのオブジェクトはクラスのコンパニオン オブジェクトと呼ばれます。

クラスとそのコンパニオン オブジェクトは同じソース ファイルで定義する必要があります。このクラスは、このシングルトン オブジェクトのコンパニオン クラスと呼ばれます。

クラスとそのコンパニオン オブジェクトは、互いのプライベート メンバーにアクセスできます。

  1. オブジェクトテスト{
  2. プライベート変数= "ビッグデータ"  
  3.  
  4. def main(args: Array[String]): 単位 = {
  5. valテスト = 新しいテスト()
  6. println(テスト名を更新します())
  7. }
  8. }
  9.  
  10. クラステスト{
  11. def update_name(): 文字列 = {
  12. テスト。 name = "左手と右手"  
  13. テスト名 
  14. }
  15.  
  16. }

特性

Scala のトレイトは Java のインターフェースと同等ですが、実際にはインターフェースよりも強力です。インターフェースとは異なり、プロパティとメソッドの実装も定義できます。

通常、Scala クラスは単一の親クラスからのみ継承できますが、特性の場合は複数の親クラスから継承できます。その結果、多重継承が実装されます(キーワード with)。実際、Scala の特性は Java の抽象クラスに似ています。

  1. オブジェクト Test は UserImp をAddressImp拡張します{
  2. def getUserName() をオーバーライドします: String = ???
  3.  
  4. def getAddress() をオーバーライドします: String = ???
  5. }
  6.  
  7. 特性 UserImp{
  8. def getUserName():文字列
  9. }
  10.  
  11. 特性アドレスImp{
  12. デフgetAddress():文字列
  13. }

パターンマッチング

Java の switch を例に挙げてみましょう。 Java の switch は、いくつかの基本的な型マッチングのみを実行し、いくつかのアクションを実行しますが、戻り値はありません。

Scala のパターン マッチングははるかに強力です。値の一致に加えて、型の一致も可能です。

  1. def calculate(シンボル:文字列): (文字列,文字列)=>文字列 ={
  2. シンボルマッチ {
  3. 場合  "スプライシング方法 1" => (a:String,b:String)=> s "スプライシング方法 1:$a,$b"  
  4. 場合  「連結方法 2」 => (a:String,b:String)=> s 「連結方法 2: $b 、 $a」  
  5. }
  6. }

私が驚いたのは(ほんの数行ですが)

  1. クイックソート
  2.  
  3. def quickSort(list: List[ Int ]): List[ Int ] = リストの一致 {
  4. ケースNil => Nil
  5. ケースリスト() => リスト()
  6. ケースヘッド :: テール =>
  7. val ( left , right ) = tail.partition(_ < head)
  8. クイックソート() ::: ヘッド :: クイックソート()
  9. }
  10.    
  11. マージ
  12.  
  13. def merge(: List[ Int ],: List[ Int ]): List[ Int ] = (,) 一致 {
  14. case (Nil, _) =>正しい 
  15. case (_, Nil) => 
  16. ケース(x::xTail, y::yTail) =>
  17. x <= y の場合、 x :: merge(xTail, right )
  18. そうでない場合はy :: merge( left , yTail)
  19. }

暗黙的な変換

Scala が提供する暗黙的な変換と暗黙的なパラメータ関数は非常に特徴的な機能です。これはJavaなどのプログラミング言語にはない機能です。特定のタイプのオブジェクトを別のタイプのオブジェクトに変換するように手動で指定できます。これらの機能を通じて、非常に強力で特別な機能を実現できます。

ルール

(1)暗黙的な変換を使用する前に、importを使用して現在のスコープへの暗黙的な変換を参照するか、スコープ内で暗黙的な変換を定義する必要があります。

(2)暗黙的な変換は、他の変換が利用できない場合にのみ実行できます。同じスコープ内の同じソース タイプに対して複数の暗黙的な変換関数が定義されている場合、複数の暗黙的な変換関数が一致する可能性があるとコンパイラはエラーを報告します。そのため、使用時には不要な暗黙的な定義を削除してください。

暗黙的なデータ型の変換

String 型は Int 型に自動的に変換できないため、String 型の値を Int 型の変数または定数に割り当てると、コンパイラはエラーを報告します。しかし.....

  1. 暗黙的な def strToInt(str: String) = str.toInt
  2. def main(args: Array[String]): 単位 = {
  3. 値 a: Int = "100"  
  4.    
  5. 印刷(a)
  6. }

パラメータの暗黙的な変換

いわゆる暗黙のパラメータとは、関数またはメソッド内で implicit によって変更されるパラメータを指します。このとき、Scala は、暗黙の値、つまり暗黙の値で変更された指定された型のオブジェクトを見つけて、パラメータを注入しようとします。

  1. オブジェクトテスト{
  2. プライベート変数= "ビッグデータ"  
  3. 暗黙の val test = new Test
  4.  
  5. def getName(暗黙のテスト:テスト): ユニット ={
  6. println(テスト名を更新します())
  7. }
  8. def main(args: Array[String]): 単位 = {
  9. 名前を取得する
  10. }
  11. }
  12.  
  13. クラステスト{
  14. def update_name(): 文字列 = {
  15. テスト。 name = "左手と右手"  
  16. テスト名 
  17. }
  18.  
  19. }

<<:  マルチクラウドおよびハイブリッドクラウドシナリオにおけるデータ同期ソリューション: Kafka

>>:  クラウドネイティブアプリケーションを保護する方法

推薦する

今日のウェブマスターはトラを恐れている

今日のウェブマスター、特に私たちの草の根ウェブマスターは、「虎」という言葉を聞くと恐怖を感じます。こ...

SEOの友人たちに指示を出します

この間、グループを立ち上げましたが、多くの問題が見つかりました。グループを立ち上げた目的をいつも疑う...

愛のサポート、インターネットの新時代のビジネスモデルについての簡単な議論

【ポイント】 新しいインターネット時代では、ユーザーが製品を使用する動機は、必要性から好みへと変化し...

2020年のクラウドコンピューティングの展望: マルチクラウド管理がさらに高レベルへ

過去 1 年間、ハイブリッド クラウドとマルチ クラウドが話題となってきました。サービスを提供するた...

cn2 gia+cuii に接続された hostyun の「[Los Angeles kr-native]」VPS シリーズの簡単なレビュー

Hostyun は、ロサンゼルス KR データセンターにかなりの数のマシンを導入しています。VPS ...

Kubernetes クラスターで Iptables を Ipvs に置き換える方法

k8s の kube-proxy はネットワーク プロキシであり、Kubernetes クラスター内...

コンテンツマーケティング記事を書くためのヒント

一定のライティングスキルを持つことは、インターネット マーケターの基本的なスキルであると言えるでしょ...

georgedatacenter: 年間 84 ドル、8G メモリ/4 コア (AMD)/50g NVMe/1Gbps 帯域幅 (トラフィック無制限)

georgedatacenter (2009 年設立) は現在、ロサンゼルス、カンザス、アムステルダ...

フラッピーバードの裏に隠されたマーケティングルール

Flappy Bird は今年 2 月 10 日に開発元によって主要ストアから削除されましたが、その...

bettervps-512m メモリ KVM/20g ハードディスク/1T 月間トラフィック/月額 5 ドル

BetterVPS は、2011 年に Web デザイナーと開発者によって設立された ShoveHo...

トラフィックが多ければ多いほど良いというわけではありません。トラフィックを軽視することは有害であり、無意味です。

ウェブサイトのトラフィックは、ウェブマスターが常に追求する目標です。ウェブサイトが収益を上げたい場合...

ウェブサイト最適化スーパーバイザーは、SEO 最適化スキルの初心者を効果的にトレーニングするにはどうすればよいでしょうか?

中小企業は、ウェブサイトの最適化に取り組む際に、スタッフの急速な離職という問題に直面することが多く、...

pqhosting: オランダ\ロシア\モルドバ、VPS\専用サーバー、無制限のトラフィック、月額1ユーロから、ビットコイン決済

「PQ Hosting」SRLはモルドバに設立されたホスティング会社です。オランダ(Serveriu...

K8S を学びたいなら、DaemonSet は非常に重要です!収集する価値がある

今日は、[Kubernetes] DaemonSet の詳細な説明を共有して、履歴書を充実させ、面接...

A5 ウェブマスター ネットワーク トピック: 今日の JD.com、Suning、Gome 間の戦争は単なる仕掛けか、それとも本物か?

A5ウェブマスターネットワークによると、数ヶ月間激化していた電子商取引の価格戦争は本日午前9時に最高...