これが 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

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

推薦する

百度、画像読み取り検索エンジンの時代に突入

2014年1月17日、百度ウェブマスタープラットフォームは、李氏が執筆した「画像読み取りの時代へ」と...

インターネットマーケティングソリューションの提供はSEOの未来です

現在、SEO 業界では次のような現象が起きています。初心者が Web サイト最適化ビジネスの注文を熱...

v.psはどうですか?香港CMIネットワークのVPSの簡単なレビュー

v.ps は現在、香港データセンターに新しい MINI KVM VPS を導入しています。デフォルト...

360 Search は市場シェアの 25% を占めています。360 の秘訣は何でしょうか?

11月6日のニュース:360 Searchの市場シェアが25%に達したと報じられており、これはBai...

ウェブサイトのキーワードランキングを向上させるユーザーのニーズを調査

ユーザーはウェブサイトのランキングに影響を与えますか? 影響を与えない場合、影響はないので、ユーザー...

総合的なトラフィックに基づくWeiboマーケティング

皆さんは「Weibo」という言葉をすでにご存知だと思います。2006年の発展から現在まで、Sina ...

企業がIoT分析にエッジコンピューティングを活用する方法

現在、企業における IoT の導入により、エッジ ゲートウェイやハイパーコンバージド インフラストラ...

「MQ シリーズをマスターする」 - カフカの Ren 子午線と Du 子午線を開く

[[394499]]みなさんこんにちは。私はウー兄弟です。これは、Kafka のアーキテクチャ設計に...

企業にとって新しいウェブサイトの最適化はどれほど重要ですか?

ショートビデオ、セルフメディア、インフルエンサーのためのワンストップサービスインターネット時代の到来...

PPTVの結婚については噂が絶えない。どちらを選ぶのだろうか?

昨年と今年、インターネット動画業界では2つの結婚が大きな注目を集めた。1つはYoukuとTudouの...

通信会社は最近、cn2 gia 市場を是正しています。こちらは、米国の cn2 gia 回線をまだ販売している VPS 販売業者のリストです。

道端のコミュニティからの噂:中国電信はcn2 giaを違法に販売する者を処罰するだろうあるいは市場を...

タオバオの公式デザイン変更がリーク、今月末までに完了する可能性

10月25日、ある商人が易邦電力網に明らかにしたところによると、タオバオは昨日から改訂された新ホーム...

新しいブランドや製品のコンテンツマーケティングをどのように実施すればよいでしょうか?

ショートビデオ、セルフメディア、インフルエンサーのためのワンストップサービスコンテンツ マーケティン...

検索最適化: 検索マーケティングは「最適化の時代」に突入

これまで常に価格によってランキングが決定されてきた検索入札市場では、ゲームのルールに新たな変化が見ら...

広告の効果が低下しているにもかかわらず、大手ブランドはなぜ依然として大規模な広告に熱心なのでしょうか?

現代の情報化社会に生きる私たちは、トイレに行く時、飛行機に乗る時、エレベーターに乗る時など、いつどこ...