Swift-quick-guide

提供:Dev Guides
移動先:案内検索

Swift-概要

Swift 4は、Apple IncがiOSおよびOS X開発用に開発した新しいプログラミング言語です。 Swift 4は、Cの互換性の制約なしに、CとObjective-Cのベストを採用しています。

  • Swift 4は安全なプログラミングパターンを利用します。
  • Swift 4は最新のプログラミング機能を提供します。
  • Swift 4は、Objective-Cのような構文を提供します。
  • Swift 4は、iOSおよびOS Xアプリを作成する素晴らしい方法です。
  • Swift 4は、既存のCocoaフレームワークへのシームレスなアクセスを提供します。
  • Swift 4は、言語の手続き型部分とオブジェクト指向部分を統合します。 *Swift 4は、入出力や文字列処理などの機能をサポートするために、個別のライブラリインポートを必要としません。

Swift 4は、Mac OSおよびiOSの既存のObj-Cシステムと同じランタイムを使用します。これにより、Swift 4プログラムを多くの既存のiOS 6およびOS X 10.8プラットフォームで実行できます。

Swift 4には、Swift 4プログラマーがコードを記述して実行し、すぐに結果を確認できるプレイグラウンド機能が備わっています。

Swiftの最初のパブリックリリースは2010年にリリースされました。* Chris Lattner *が最初の公式バージョンを作成するのにほぼ14年かかり、その後、他の多くの貢献者によってサポートされました。 Swift 4はXcode 6ベータに含まれています。

Swiftデザイナーは、Objective-C、Rust、Haskell、Ruby、Python、C#、CLUなど、他のさまざまな一般的な言語からアイデアを取り入れました。

Swift-環境

ローカル環境のセットアップ

Swift 4は学習目的でPlaygroundプラットフォームを提供します。これを同じようにセットアップします。 PlaygroundでSwift 4コーディングを開始するには、xCodeソフトウェアが必要です。 Swift 4の概念に慣れたら、iOS/OS xアプリケーション開発にxCode IDEを使用できます。

まず、Apple Developer Webサイトにすでにアカウントがあると考えています。 ログインしたら、次のリンクにアクセスしてください-https://idmsa.apple.com/IDMSWebAuth/login?appIdKey=891bd3417a7776362562d2197f89480a8547b108fd934911bcbea0110d07f757&path=%2Fdownload%2Fmore%2F&rv=1[Apple開発者向けダウンロード]

これは、次のように利用可能なソフトウェアの数をリストします-

ソフトウェアリスト

次に、xCodeを選択し、ディスクイメージの近くにある特定のリンクをクリックしてダウンロードします。 dmgファイルをダウンロードした後、それをダブルクリックし、指示に従ってインストールすることができます。 最後に、指定された指示に従い、xCodeアイコンをApplicationフォルダーにドロップします。

Xcode

これで、マシンにxCodeがインストールされました。 次に、アプリケーションフォルダーからXcodeを開き、契約条件に同意してから続行します。 すべてがうまくいけば、次の画面が表示されます-

Open Xcode

[遊び場で始める]オプションを選択し、遊び場の名前を入力して、プラットフォームとしてiOSを選択します。 最後に、次のようにプレイグラウンドウィンドウが表示されます-

プレイグラウンドウィンドウ

以下は、デフォルトのSwift 4 Playgroundウィンドウから取られたコードです。

import UIKit
var str = "Hello, playground"

あなたがOS Xプログラムのために同じプログラムを作成する場合、それはインポートココアが含まれ、プログラムは次のようになります-

import Cocoa
var str = "Hello, playground"

上記のプログラムが読み込まれると、プレイグラウンドの結果領域(右側)に次の結果が表示されます。

Hello, playground

おめでとうございます。Swift4プログラミング環境の準備が整いました。学習媒体「チュートリアルポイント」に進むことができます。

Swift-基本的な構文

環境のセットアップ中に、Swift 4プログラムの一部を見てきました。 OS Xプレイグラウンド用に作成された次の* Hello、World!プログラムからもう一度始めましょう。これには、以下に示す *import Cocoa が含まれます-

/*My first program in Swift 4*/
var myString = "Hello, World!"

print(myString)

あなたがiOSの遊び場のために同じプログラムを作成する場合、それは import UIKit を含み、プログラムは次のようになります-

import UIKit
var myString = "Hello, World!"
print(myString)

適切な遊び場を使用して上記のプログラムを実行すると、次の結果が得られます-

Hello, World!

Swift 4プログラムの基本構造を見てみましょう。Swift4プログラミング言語の基本的な構成要素を簡単に理解できるようになります。

Swift 4でのインポート

*import* ステートメントを使用して、Objective-Cフレームワーク(またはCライブラリ)をSwift 4プログラムに直接インポートできます。 たとえば、上記の *import cocoa* ステートメントは、すべてのOS Xの開発レイヤーを形成するすべてのCocoaライブラリ、API、およびランタイムをSwift 4で使用可能にします。

Cocoaは、CのスーパーセットであるObjective-Cに実装されているため、Swift 4アプリケーションにCとC ++を混在させることは簡単です。

Swift 4のトークン

Swift 4プログラムはさまざまなトークンで構成され、トークンはキーワード、識別子、定数、文字列リテラル、またはシンボルのいずれかです。 たとえば、次のSwift 4ステートメントは3つのトークンで構成されています-

print("test!")
The individual tokens are:
print("test!")

コメント

コメントは、Swift 4プログラムのテキストを支援するようなものです。 それらはコンパイラーによって無視されます。 以下に示すように、複数行のコメントは/で始まり、文字/で終わります-

/*My first program in Swift 4*/

Swift 4では、複数行のコメントをネストできます。 以下は、Swift 4の有効なコメントです-

/* My first program in Swift 4 is Hello, World!
/*Where as second program is Hello, Swift 4!*/*/

単一行コメントは、コメントの先頭に//を使用して記述されます。

//My first program in Swift 4

セミコロン

Swift 4では、コード内の各ステートメントの後にセミコロン(;)を入力する必要はありませんが、オプションです。セミコロンを使用する場合、コンパイラはそれについて文句を言いません。

ただし、同じ行で複数のステートメントを使用している場合、区切り文字としてセミコロンを使用する必要があります。そうしないと、コンパイラーは構文エラーを発生させます。 上記のHello、World!を書くことができます。 次のようなプログラム-

/*My first program in Swift 4*/
var myString = "Hello, World!"; print(myString)

識別子

Swift 4識別子は、変数、関数、またはその他のユーザー定義アイテムを識別するために使用される名前です。 識別子は、アルファベットA〜Zまたはa〜zまたはアンダースコア_で始まり、その後に0個以上の文字、アンダースコア、および数字(0〜9)が続きます。

Swift 4では、識別子内で@、$、%などの特殊文字を使用できません。 Swift 4は、*大文字と小文字を区別*するプログラミング言語です。 したがって、Swift 4では、Manpowerとmanpowerは2つの異なる識別子です。 ここに受け入れ可能な識別子のいくつかの例があります-

Azad        zara   abc   move_name   a_123
myname50    _temp  j     a23b9       retVal

予約語を識別子として使用するには、その前後にバックティック( `)を付ける必要があります。 たとえば、 class は有効な識別子ではありませんが、 `* class *`は有効です。

キーワード

次のキーワードはSwift 4で予約されています。 これらの予約語は、バッククォートでエスケープされていない限り、定数、変数、またはその他の識別子名として使用できません-

宣言で使用されるキーワード

Class deinit Enum extension
Func import Init internal
Let operator private protocol
public static struct subscript
typealias var

ステートメントで使用されるキーワード

break case continue default
do else fallthrough for
if in return switch
where while

式と型で使用されるキーワード

as dynamicType false is
nil self Self super
true COLUMN FILE FUNCTION
LINE

特定のコンテキストで使用されるキーワード

associativity convenience dynamic didSet
final get infix inout
lazy left mutating none
nonmutating optional override postfix
precedence prefix Protocol required
right set Type unowned
weak willSet

空白

コメントが含まれている可能性がある空白のみを含む行は空白行と呼ばれ、Swift 4コンパイラはそれを完全に無視します。

空白は、空白、タブ、改行文字、コメントを記述するためにSwift 4で使用される用語です。 空白はステートメントの一部を別の部分から分離し、コンパイラーがintなどのステートメントの1つの要素がどこで終了し、次の要素が始まるかを識別できるようにします。 したがって、次のステートメントで-

var age

コンパイラがそれらを区別できるようにするには、 varage の間に少なくとも1つの空白文字(通常はスペース)が必要です。 一方、次の文で-

int fruit = apples + oranges  //get the total fruits

果物と=、または=とリンゴの間には空白文字は必要ありませんが、読みやすくするために自由に含めることができます。

たとえば、演算子の両側のスペースは等しくなければなりません。

int fruit = apples +oranges   //is a wrong statement
int fruit = apples + oranges  //is a Correct statement

リテラル

リテラルは、整数、浮動小数点数、または文字列型の値のソースコード表現です。 以下は、リテラルの例です-

92              //Integer literal
4.24159         //Floating-point literal
"Hello, World!" //String literal

Swiftでの印刷

迅速に何かを印刷するには、「印刷」キーワードを使用します。

印刷には3つの異なるプロパティがあります。

アイテム –印刷するアイテム

*Separator* –アイテム間のセパレーター

ターミネーター –行の終わりの値。同じ例と構文を見てみましょう。

print("Items to print", separator: "Value " , terminator: "Value")
//E.g. of print statement.

print("Value one")
//prints "Value one \n" Adds, \n as terminator and " " as separator by
default.

print("Value one","Value two", separator: " Next Value" , terminator: " End")
//prints "Value one Next Value Value two End"

上記のコードでは、最初のprintステートメントはデフォルトで\ n、改行フィードをターミネーターとして追加します。

要件に応じて、カスタムのセパレーターとターミネーターを提供できます。

Swift-データ型

プログラミング言語でプログラミングを行っている間、さまざまなタイプの変数を使用して情報を保存する必要があります。 変数は、値を保存するために予約されたメモリの場所に他なりません。 これは、変数を作成するときに、メモリ内にスペースを確保することを意味します。

文字列、文字、ワイド文字、整数、浮動小数点、ブールなどのさまざまなデータ型の情報を保存することができます。 変数のデータ型に基づいて、オペレーティングシステムはメモリを割り当て、予約メモリに保存できるものを決定します。

組み込みデータ型

Swift 4は、プログラマーに豊富な品揃えの組み込みおよびユーザー定義のデータ型を提供します。 基本的なデータ型の次のタイプは、変数を宣言するときに最も頻繁にあります-

  • IntまたはUInt -これは整数に使用されます。 具体的には、Int32、Int64を使用して32または64ビットの符号付き整数を定義し、UInt32またはUInt64を使用して32または64ビットの符号なし整数変数を定義できます。 たとえば、42および-23。
  • Float -これは、32ビットの浮動小数点数とより小さい小数点を持つ数値を表すために使用されます。 たとえば、3.14159、0.1、および-273.158。
  • Double -これは、64ビットの浮動小数点数を表すために使用され、浮動小数点値が非常に大きくなければならない場合に使用されます。 たとえば、3.14159、0.1、および-273.158。
  • Bool -これは、trueまたはfalseのブール値を表します。
  • String -これは文字の順序付けられたコレクションです。 たとえば、「He​​llo、World!」
  • 文字-これは単一文字の文字列リテラルです。 たとえば、「C」
  • オプション-これは、値を保持するか値を保持しない変数を表します。
  • タプル-複数の値を単一の複合値にグループ化するために使用されます。

ここに、整数型に関連するいくつかの重要なポイントをリストしました-

  • 32ビットプラットフォームでは、IntはInt32と同じサイズです。
  • 64ビットプラットフォームでは、IntはInt64と同じサイズです。
  • 32ビットプラットフォームでは、UIntはUInt32と同じサイズです。
  • 64ビットプラットフォームでは、UIntはUInt64と同じサイズです。
  • Int8、Int16、Int32、Int64を使用して、8ビット、16ビット、32ビット、および64ビット形式の符号付き整数を表すことができます。
  • UInt8、UInt16、UInt32、およびUInt64を使用して、8ビット、16ビット、32ビット、および64ビット形式の符号なし整数を表すことができます。

バインドされた値

次の表は、変数の種類、メモリに値を保存するのに必要なメモリ量、およびそのような種類の変数に保存できる最大値と最小値を示しています。

Type Typical Bit Width Typical Range
Int8 1byte -127 to 127
UInt8 1byte 0 to 255
Int32 4bytes -2147483648 to 2147483647
UInt32 4bytes 0 to 4294967295
Int64 8bytes -9223372036854775808 to 9223372036854775807
UInt64 8bytes 0 to 18446744073709551615
Float 4bytes 1.2E-38 to 3.4E+38 (~6 digits)
Double 8bytes 2.3E-308 to 1.7E+308 (~15 digits)

タイプエイリアス

*typealias* を使用して、既存のタイプの新しい名前を作成できます。 typealiasを使用して新しい型を定義する簡単な構文を次に示します-
typealias newname = type

たとえば、次の行は、 FeetInt の別名であることをコンパイラに指示します-

typealias Feet = Int

さて、次の宣言は完全に正当であり、距離と呼ばれる整数変数を作成します-

typealias Feet = Int
var distance: Feet = 100
print(distance)

プレイグラウンドを使用して上記のプログラムを実行すると、次の結果が得られます。

100

タイプセーフティ

Swift 4はタイプセーフな言語です。つまり、コードの一部がStringを想定している場合、誤ってIntを渡すことはできません。

Swift 4はタイプセーフなので、コードのコンパイル時にタイプチェックを実行し、不一致のタイプがある場合はエラーとしてフラグを立てます。

var varA = 42
varA = "This is hello"
print(varA)

上記のプログラムをコンパイルすると、次のコンパイル時エラーが発生します。

main.swift:2:8: error: cannot assign value of type 'String' to type 'Int'
varA = "This is hello"

型推論

型推論により、コンパイラは、指定した値を調べるだけで、コードをコンパイルするときに特定の式の型を自動的に推測できます。 Swift 4は型推論を使用して、次のように適切な型を算出します。

//varA is inferred to be of type Int
var varA = 42
print(varA)

//varB is inferred to be of type Double
var varB = 3.14159
print(varB)

//varC is also inferred to be of type Double
var varC = 3 + 0.14159
print(varC)

プレイグラウンドを使用して上記のプログラムを実行すると、次の結果が得られます-

42
3.14159
3.14159

Swift-変数

変数は、プログラムが操作できる名前付きストレージを提供します。 Swift 4の各変数には、変数のメモリのサイズとレイアウトを決定する特定のタイプがあります。そのメモリ内に保存できる値の範囲。変数に適用できる一連の操作。

スウィフト4は、変数の次の基本的なタイプをサポートしています-

  • IntまたはUInt -これは整数に使用されます。 具体的には、Int32、Int64を使用して32または64ビットの符号付き整数を定義し、UInt32またはUInt64を使用して32または64ビットの符号なし整数変数を定義できます。 たとえば、42および-23。
  • Float -これは、32ビットの浮動小数点数を表すために使用されます。 小数点以下の数字を保持するために使用されます。 たとえば、3.14159、0.1、および-273.158。
  • Double -これは、64ビットの浮動小数点数を表すために使用され、浮動小数点値が非常に大きくなければならない場合に使用されます。 たとえば、3.14159、0.1、および-273.158。
  • Bool -これは、trueまたはfalseのブール値を表します。
  • String -これは文字の順序付けられたコレクションです。 たとえば、「He​​llo、World!」
  • 文字-これは単一文字の文字列リテラルです。 たとえば、「C」

Swift 4では、 Optional、Array、Dictionaries、StructuresClasses など、他のさまざまなタイプの変数を定義することもできます。

次のセクションでは、Swift 4プログラミングでさまざまなタイプの変数を宣言して使用する方法について説明します。

可変宣言

変数宣言は、変数のストレージを作成する場所と量をコンパイラーに指示します。 あなたが変数を使用する前に、次のように var キーワードを使用してそれらを宣言する必要があります-

var variableName = <initial value>

次の例は、Swift 4で変数を宣言する方法を示しています-

var varA = 42
print(varA)

プレイグラウンドを使用して上記のプログラムを実行すると、次の結果が得られます-

42

タイプ注釈

変数を宣言するときに* typeアノテーション*を指定して、変数が格納できる値の種類を明確にすることができます。 ここに構文があります-

var variableName:<data type> = <optional initial value>

次の例は、アノテーションを使用してSwift 4で変数を宣言する方法を示しています。 ここで重要なのは、型注釈を使用していない場合、変数の初期値を提供することが必須になり、そうでない場合は型注釈を使用して変数を宣言するだけであることに注意することです。

var varA = 42
print(varA)

var varB:Float

varB = 3.14159
print(varB)

プレイグラウンドを使用して上記のプログラムを実行すると、次の結果が得られます-

42
3.1415901184082

変数の命名

変数の名前は、文字、数字、およびアンダースコア文字で構成できます。 文字またはアンダースコアで始まる必要があります。 Swift 4は大文字と小文字を区別するプログラミング言語であるため、大文字と小文字は区別されます。

単純文字またはUnicode文字を使用して、変数に名前を付けることができます。 次の例は、変数に名前を付ける方法を示しています-

var _var = "Hello, Swift 4!"
print(_var)

var 你好 = "你好世界"
print(你好)

プレイグラウンドを使用して上記のプログラムを実行すると、次の結果が得られます。

Hello, Swift 4!
你好世界

変数の印刷

print関数を使用して、定数または変数の現在の値を印刷できます。 あなたは括弧で名前をラップすることにより変数値を補間し、開き括弧の前にバックスラッシュでエスケープすることができます:以下は有効な例です-

var varA = "Godzilla"
var varB = 1000.00

print("Value of \(varA) is more than \(varB) millions")

プレイグラウンドを使用して上記のプログラムを実行すると、次の結果が得られます。

Value of Godzilla is more than 1000.0 millions

Swift-オプション

Swift 4は、値の不在を処理する Optionals タイプも導入します。 オプションでは、「値があり、xと等しい」または「値がまったくない」と表示されます。

Optionalはそれ自体がタイプで、実際にはSwift 4の新しい超強力な列挙型の1つです。 2つの可能な値、 None と* Some(T)があります。ここで、 *T は、Swift 4で使用可能な正しいデータ型の関連付けられた値です。

これはオプションの整数宣言です-

var perhapsInt: Int?

これはオプションの文字列宣言です-

var perhapsStr: String?

上記の宣言は、値を意味しない nil に明示的に初期化することと同等です-

var perhapsStr: String? = nil

Swift 4でオプションがどのように機能するかを理解するために、次の例を見てみましょう-

var myString:String? = nil

if myString != nil {
   print(myString)
} else {
   print("myString has nil value")
}

プレイグラウンドを使用して上記のプログラムを実行すると、次の結果が得られます-

myString has nil value

オプションは、Objective-Cでポインターを使用して nil を使用するのと似ていますが、クラスだけでなく、どのタイプでも機能します。

強制開封

変数を optional として定義した場合、この変数から値を取得するには、 unwrap する必要があります。 これは、変数の最後に感嘆符を付けることを意味します。

簡単な例を見てみましょう-

var myString:String?

myString = "Hello, Swift 4!"

if myString != nil {
   print(myString)
} else {
   print("myString has nil value")
}

プレイグラウンドを使用して上記のプログラムを実行すると、次の結果が得られます-

Optional("Hello, Swift 4!")

今、変数の正しい値を取得するためにアンラッピングを適用しましょう-

var myString:String?

myString = "Hello, Swift 4!"

if myString != nil {
   print( myString! )
} else {
   print("myString has nil value")
}

プレイグラウンドを使用して上記のプログラムを実行すると、次の結果が得られます。

Hello, Swift 4!

自動展開

疑問符の代わりに感嘆符を使用して、オプションの変数を宣言できます。 このようなオプションの変数は自動的に展開され、割り当てられた値を取得するために変数の最後に感嘆符を追加する必要はありません。 簡単な例を見てみましょう-

var myString:String!
myString = "Hello, Swift 4!"

if myString != nil {
   print(myString)
} else {
   print("myString has nil value")
}

プレイグラウンドを使用して上記のプログラムを実行すると、次の結果が得られます-

Hello, Swift 4!

オプションのバインディング

オプションのバインディングを使用して、オプションに値が含まれているかどうかを確認し、含まれている場合は、その値を一時的な定数または変数として使用できるようにします。

*if* ステートメントのオプションのバインディングは次のとおりです-
if let constantName = someOptional {
   statements
}

オプションのバインディングの使用法を理解するために簡単な例を見てみましょう-

var myString:String?
myString = "Hello, Swift 4!"

if let yourString = myString {
   print("Your string has - \(yourString)")
} else {
   print("Your string does not have a value")
}

プレイグラウンドを使用して上記のプログラムを実行すると、次の結果が得られます-

Your string has - Hello, Swift 4!

スイフト-タプル

Swift 4では、 Tuples タイプも導入されています。これは、複数の値を単一の複合値にグループ化するために使用されます。

タプルの値は任意のタイプにすることができ、同じタイプである必要はありません。

たとえば、( "Tutorials Point"、123)は、2つの値を持つタプルです。1つは文字列Typeで、もう1つは整数型です。 これは正当なコマンドです。

let ImplementationError =(501、 "未実装")は、サーバー上の何かが実装されていない場合のエラーです。2つの値を返します。 エラーコードと説明。

必要な数の値と任意の数の異なるデータ型からタプルを作成できます。

タプル宣言の構文は次のとおりです-

var TupleName = (Value1, value2,… any number of values)

これがタプル宣言です-

var error501 = (501, “Not implemented”)

0から始まるインデックス番号を使用して、タプルの値にアクセスできます。

タプル値にアクセスする例を次に示します-

print(“The code is\(error501.0)”)
print(“The definition of error is\(error501.1)”)

宣言中にタプルの変数に名前を付けることができ、それらの名前を使用して呼び出すことができます

var error501 = (errorCode: 501, description: “Not Implemented”)
print(error501.errorCode)  //prints 501.

タプルは、関数から複数の値を返すのに役立ちます。 同様に、Webアプリケーションは、タイプ( "String"、Int)のタプルを返し、ロードが成功したか失敗したかを示す場合があります。

タプルで異なる値を返すことにより、異なるタプルタイプに応じて決定を下すことができます。

注意-タプルは一時的な値に役立ち、複雑なデータには適していません。

スイフト-定数

定数は、プログラムの実行中に変更されない可能性がある固定値を指します。 定数には、_integer定数、浮動定数、文字定数、または文字列リテラル_などの基本的なデータ型を使用できます。 _列挙定数_もあります。

  • 定数*は通常の変数と同様に扱われますが、定義後に値を変更することはできません。

定数宣言

定数を使用する前に、次のように let キーワードを使用して定数を宣言する必要があります-

let constantName = <initial value>

以下は、Swift 4で定数を宣言する方法を示す簡単な例です-

let constA = 42
print(constA)

プレイグラウンドを使用して上記のプログラムを実行すると、次の結果が得られます-

42

タイプ注釈

定数を宣言するときに* typeアノテーション*を指定して、定数が格納できる値の種類を明確にすることができます。 以下は構文です-

var constantName:<data type> = <optional initial value>

次の例は、アノテーションを使用してSwift 4で定数を宣言する方法を示しています。 ここでは、定数を作成しながら初期値を提供することが必須であることに注意することが重要です-

let constA = 42
print(constA)

let constB:Float = 3.14159
print(constB)

プレイグラウンドを使用して上記のプログラムを実行すると、次の結果が得られます。

42
3.1415901184082

命名定数

定数の名前は、文字、数字、およびアンダースコア文字で構成できます。 文字またはアンダースコアで始まる必要があります。 Swift 4は大文字と小文字を区別するプログラミング言語であるため、大文字と小文字は区別されます。

単純文字またはUnicode文字を使用して、変数に名前を付けることができます。 以下は有効な例です-

let _const = "Hello, Swift 4!"
print(_const)

let 你好 = "你好世界"
print(你好)

プレイグラウンドを使用して上記のプログラムを実行すると、次の結果が得られます-

Hello, Swift 4!
你好世界

印刷定数

*print* 関数を使用して、定数または変数の現在の値を印刷できます。 あなたは括弧で名前をラップすることにより変数値を補間し、開き括弧の前にバックスラッシュでエスケープすることができます:以下は有効な例です-
let constA = "Godzilla"
let constB = 1000.00

print("Value of \(constA) is more than \(constB) millions")

プレイグラウンドを使用して上記のプログラムを実行すると、次の結果が得られます-

Value of Godzilla is more than 1000.0 millions

Swift-リテラル

リテラルは、整数、浮動小数点数、または文字列型の値のソースコード表現です。 以下は、リテラルの例です-

42               //Integer literal
3.14159          //Floating-point literal
"Hello, world!"  //String literal

整数リテラル

整数リテラルは、10進、2進、8進、または16進定数です。 2進リテラルは0bで始まり、8進リテラルは0oで始まり、16進リテラルは0xで始まり、10進の場合は何もありません。

ここに整数リテラルのいくつかの例があります-

let decimalInteger = 17        //17 in decimal notation
let binaryInteger = 0b10001    //17 in binary notation
let octalInteger = 0o21        //17 in octal notation
let hexadecimalInteger = 0x11  //17 in hexadecimal notation

浮動小数点リテラル

浮動小数点リテラルには、整数部、小数点、小数部、指数部があります。 浮動小数点リテラルは、10進形式または16進形式で表現できます。

10進浮動小数点リテラルは、10進数字のシーケンスと、それに続く10進小数、10進指数、またはその両方で構成されます。

16進浮動小数点リテラルは、0xプレフィックスと、それに続くオプションの16進小数、16進指数で構成されます。

浮動小数点リテラルの例をいくつか示します-

let decimalDouble = 12.1875
let exponentDouble = 1.21875e1
let hexadecimalDouble = 0xC.3p0

文字列リテラル

文字列リテラルは、次の形式で、二重引用符で囲まれた文字のシーケンスです-

"characters"

文字列リテラルには、エスケープされていない二重引用符( ")、エスケープされていないバックスラッシュ(\)、キャリッジリターン、またはラインフィードを含めることはできません。 次のエスケープシーケンスを使用して、文字列リテラルに特殊文字を含めることができます-

Escape sequence Meaning
\0 Null Character
\\ \character
\b Backspace
\f Form feed
\n Newline
\r Carriage return
\t Horizontal tab
\v Vertical tab
\' Single Quote
\" Double Quote
\000 Octal number of one to three digits
\xhh…​ Hexadecimal number of one or more digits

次の例は、いくつかの文字列リテラルを使用する方法を示しています-

let stringL = "Hello\tWorld\n\nHello\'Swift 4\'"
print(stringL)

プレイグラウンドを使用して上記のプログラムを実行すると、次の結果が得られます-

Hello World

Hello'Swift 4'

ブールリテラル

3つのブールリテラルがあり、それらは標準のSwift 4キーワードの一部です-

  • trueを表す true の値。
  • falseを表す false の値。
  • 値なしを表す nil の値。

Swift-オペレーター

演算子は、特定の数学的または論理的な操作を実行するようコンパイラーに指示する記号です。 Objective-Cは組み込み演算子が豊富であり、次の種類の演算子を提供します-

  • 算術演算子
  • 比較演算子
  • 論理演算子
  • ビット演算子
  • 割り当て演算子
  • 範囲演算子
  • その他の演算子

このチュートリアルでは、算術演算、リレーショナル演算、論理演算、ビット単位の代入、およびその他の演算子を1つずつ説明します。

算術演算子

次の表は、Swift 4言語でサポートされているすべての算術演算子を示しています。 変数 A が10を保持し、変数 B が20を保持すると仮定します-

オペレーター

説明

2つのオペランドを追加します

A + Bは30を与えます

最初のオペランドから2番目のオペランドを減算します

A-Bは-10になります

*

両方のオペランドを乗算します

A* Bは200を与えます

/

分子を分母で除算します

B/Aは2を与えます

%

モジュラス演算子と整数/浮動小数点除算後の剰余

B%Aは0を返します

比較演算子

次の表は、Swift 4言語でサポートされているすべての関係演算子を示しています。 変数 A が10を保持し、変数 B が20を保持すると仮定します-

Operator Description Example
== Checks if the values of two operands are equal or not; if yes, then the condition becomes true. (A == B) is not true.
!= Checks if the values of two operands are equal or not; if values are not equal, then the condition becomes true. (A != B) is true.
> Checks if the value of left operand is greater than the value of right operand; if yes, then the condition becomes true. (A > B) is not true.
< Checks if the value of left operand is less than the value of right operand; if yes, then the condition becomes true. (A < B) is true.
>= Checks if the value of left operand is greater than or equal to the value of right operand; if yes, then the condition becomes true. (A >= B) is not true.
Checks if the value of left operand is less than or equal to the value of right operand; if yes, then the condition becomes true. (A ⇐ B) is true.

論理演算子

次の表は、Swift 4言語でサポートされているすべての論理演算子を示しています。 変数 A が1を保持し、変数 B が0を保持すると仮定します-

Operator Description Example
&& Called Logical AND operator. If both the operands are non-zero, then the condition becomes true. (A && B) is false.
Called Logical OR Operator. If any of the two operands is non-zero, then the condition becomes true. (A
B) is true. ! Called Logical NOT Operator. Use to reverses the logical state of its operand. If a condition is true, then the Logical NOT operator will make it false.

ビット演算子

ビットごとの演算子はビットに作用し、ビットごとの操作を実行します。 &、|、および^の真理値表は次のとおりです-

p q p&q p q
p^q 0 0 0 0
0 0 1 0 1
1 1 1 1 1
0 1 0 0 1
Assume A = 60; and B = 13;

In binary format, they will be as follows:

A = 0011 1100

B = 0000 1101

-----------------

A & B = 0000 1100

A|B = 0011 1101

A^B = 0011 0001

~A = 1100 0011

Swift 4言語でサポートされているビット演算子は、次の表にリストされています。 変数 A は60を保持し、変数 B は13を保持し、7-

Operator Description Example
& Binary AND Operator copies a bit to the result, if it exists in both operands. (A & B) will give 12, which is 0000 1100
Binary OR Operator copies a bit, if it exists in either operand.
(A B) will give 61, which is 0011 1101 ^
Binary XOR Operator copies the bit, if it is set in one operand but not both. (A ^ B) will give 49, which is 0011 0001 ~
Binary Ones Complement Operator is unary and has the effect of 'flipping' bits. (~A ) will give -61, which is 1100 0011 in 2’s complement form. <<
Binary Left Shift Operator. The left operands value is moved left by the number of bits specified by the right operand. (A << 2 will give 240, which is 1111 0000 >>

割り当て演算子

SSwift 4は、次の割り当て演算子をサポートしています-

Operator Description Example
= Simple assignment operator, Assigns values from right side operands to left side operand C = A + B will assign value of A + B into C
+= Add AND assignment operator, It adds right operand to the left operand and assigns the result to left operand C += A is equivalent to C = C + A
-= Subtract AND assignment operator, It subtracts right operand from the left operand and assigns the result to left operand C -= A is equivalent to C = C - A
*= Multiply AND assignment operator, It multiplies right operand with the left operand and assigns the result to left operand C *= A is equivalent to C = C * A
/= Divide AND assignment operator, It divides left operand with the right operand and assigns the result to left operand C/= A is equivalent to C = C/A
%= Modulus AND assignment operator, It takes modulus using two operands and assigns the result to left operand C %= A is equivalent to C = C % A
<⇐ Left shift AND assignment operator C <⇐ 2 is same as C = C << 2
>>= Right shift AND assignment operator C >>= 2 is same as C = C >> 2
&= Bitwise AND assignment operator C &= 2 is same as C = C & 2
^= bitwise exclusive OR and assignment operator C ^= 2 is same as C = C ^ 2
= bitwise inclusive OR and assignment operator
C = 2 is same as C = C 2

範囲演算子

Swift 4には、値の範囲を表現するためのショートカットである2つの範囲演算子が含まれています。 次の表で、これら2つの演算子について説明します。

Operator Description Example
Closed Range (a…​b) defines a range that runs from a to b, and includes the values a and b. 1…​5 gives 1, 2, 3, 4 and 5
Half-Open Range (a..< b) defines a range that runs from a to b, but does not include b. 1..< 5 gives 1, 2, 3, and 4
One- sided Range

a… , defines a range that runs from a to end of elements

…aは、startからaまでの範囲を定義します

a

1…1、2、3…の要素の終わりを与える

…2は始まりを…1,2に与えます

その他の演算子

Swift 4は、 range や?などの他の重要な演算子をサポートしています。 :次の表で説明されています。

Operator Description Example
Unary Minus The sign of a numeric value can be toggled using a prefixed - -3 or -4
Unary Plus Returns the value it operates on, without any change. +6 gives 6
Ternary Conditional Condition ? X : Y If Condition is true ? Then value X : Otherwise value Y

演算子の優先順位

演算子の優先順位は、式内の用語のグループ化を決定します。 これは、式の評価方法に影響します。 特定の演算子は、他の演算子よりも優先順位が高くなっています。たとえば、乗算演算子は加算演算子よりも優先順位が高くなります。

たとえば、x = 7 + 3 * 2;ここでは、演算子*の優先順位が+よりも高いため、xには20ではなく13が割り当てられます。したがって、最初に3 * 2で乗算され、7に加算されます。

ここでは、優先順位が最も高い演算子が表の上部に表示され、優先順位が最も低い演算子が下部に表示されます。 式内では、優先順位の高い演算子が最初に評価されます。

Operator Description Example
Primary Expression Operators () [] . expr++ expr-- left-to-right
Unary Operators
  • &-! 〜+ expr --expr

    */%

+ -

>> <<

<> <⇒ =

!=

right-to-left
Binary Operators

&

^

&&
left-to-right
Ternary Operator ?: right-to-left
Assignment Operators = += -=* =/= %= >>= <⇐ &=^= =
right-to-left Comma ,

スウィフト-意思決定

意思決定構造では、プログラマーが、プログラムによって評価またはテストされる1つ以上の条件、および条件が true であると判断された場合に実行されるステートメント、およびオプションで次の場合に実行される他のステートメントを指定する必要があります条件は false と判断されます。

以下は、ほとんどのプログラミング言語で見られる典型的な意思決定構造の一般的なものです-

意思決定

Swift 4は、次のタイプの意思決定ステートメントを提供します。 詳細を確認するには、次のリンクをクリックしてください。

Sr.No Statement & Description
1

if statement

ifステートメントは、ブール式とそれに続く1つ以上のステートメントで構成されます。

2

if…​else statement

ifステートメントの後に、ブール式がfalseの場合に実行されるオプションのelseステートメントを続けることができます。

3

if…​else if…​else Statement

ifステートメントの後にオプションのelse if …​ elseステートメントを続けることができます。これは、単一のif …​ else ifステートメントを使用してさまざまな条件をテストするのに非常に便利です。

4

nested if statements

1つのifまたはelse ifステートメントを別のifまたはelse ifステートメント内で使用できます。

5

switch statement

switchステートメントを使用すると、値のリストに対する変数の等価性をテストできます。

は? :オペレーター

条件演算子? :*前の章の *if …​ else ステートメントを置き換えるために使用できます。 それは次の一般的な形式を持っています-

Exp1 ? Exp2 : Exp3;

Exp1、Exp2、およびExp3は式です。 コロンの使用と配置に注意してください。

aの値 式は次のように決定されます:Exp1が評価されます。 真の場合、Exp2が評価され、?全体の値になります。 式です。 Exp1がfalseの場合、Exp3が評価され、その値が式の値になります。

スイフト-ループ

コードのブロックを数回実行する必要がある場合があります。 一般に、ステートメントは順番に実行されます。関数の最初のステートメントが最初に実行され、次に2番目のステートメントが実行されます。

プログラミング言語は、より複雑な実行パスを可能にするさまざまな制御構造を提供します。

ループステートメントを使用すると、ステートメントまたはステートメントのグループを複数回実行できます。 以下は、ほとんどのプログラミング言語での一般的なループ文です-

ループ

Swift 4プログラミング言語は、ループ要件を処理するために次の種類のループを提供します。 詳細を確認するには、次のリンクをクリックしてください。

Sr.No Loop Type & Description
1

for-in

このループは、範囲、シーケンス、コレクション、または進行の各アイテムに対して一連のステートメントを実行します。

2

while loop

特定の条件が真の間、ステートメントまたはステートメントのグループを繰り返します。 ループ本体を実行する前に条件をテストします。

3

repeat…​while loop

whileステートメントと似ていますが、ループ本体の最後で条件をテストします。

ループ制御ステートメント

ループ制御ステートメントは、通常のシーケンスから実行を変更します。 実行がスコープを離れると、そのスコープで作成されたすべての自動オブジェクトが破棄されます。

Swift 4は、次の制御ステートメントをサポートしています。 詳細を確認するには、次のリンクをクリックしてください。

Sr.No Control Statement & Description
1

continue statement

このステートメントは、ループに実行中の処理を停止し、ループの次の反復の開始時に再び開始するように指示します。

2

break statement

ループステートメントを終了し、ループの直後のステートメントに実行を転送します。

3

fallthrough statement

fallthroughステートメントは、Swift 4スイッチからCスタイルスイッチへの動作をシミュレートします。

スイフト-文字列

Swift 4の文字列は、「Hello、World!」などの文字の順序付きコレクションです。また、それらはSwift 4データ型 String で表され、これは Character 型の値のコレクションを表します。

文字列を作成する

次のように、文字列リテラルを使用するか、Stringクラスのインスタンスを作成することにより、文字列を作成できます-

//String creation using String literal
var stringA = "Hello, Swift 4!"
print( stringA )

//String creation using String instance
var stringB = String("Hello, Swift 4!")
print( stringB )

//Multiple line string

let stringC = """
Hey this is a
example of multiple Line
string by finddevguides

"""
print(stringC)

上記のコードをコンパイルして実行すると、次の結果が生成されます。

Hello, Swift 4!
Hello, Swift 4!
Hey this is a
example of multiple Line
string by finddevguides

空の文字列

以下に示すように、空の文字列リテラルを使用するか、Stringクラスのインスタンスを作成することにより、空の文字列を作成できます。 ブールプロパティ isEmpty を使用して、文字列が空かどうかを確認することもできます。

//Empty string creation using String literal
var stringA = ""

if stringA.isEmpty {
   print( "stringA is empty" )
} else {
   print( "stringA is not empty" )
}

//Empty string creation using String instance
let stringB = String()

if stringB.isEmpty {
   print( "stringB is empty" )
} else {
   print( "stringB is not empty" )
}

上記のコードをコンパイルして実行すると、次の結果が生成されます-

stringA is empty
stringB is empty

文字列定数

あなたは、文字列を変数に割り当てることで変更(または突然変異)できるか、または以下に示すように let キーワードを使用して定数に割り当てることで定数になるかどうかを指定できます-

//stringA can be modified
var stringA = "Hello, Swift 4!"
stringA + = "--Readers--"
print( stringA )

//stringB can not be modified
let stringB = String("Hello, Swift 4!")
stringB + = "--Readers--"
print( stringB )

上記のコードをコンパイルして実行すると、次の結果が生成されます-

Playground execution failed: error: <EXPR>:10:1: error: 'String' is not
convertible to '@lvalue UInt8'
stringB + = "--Readers--"

文字列補間

文字列補間は、定数、変数、リテラル、および式の組み合わせから新しい文字列値を構築する方法であり、その値を文字列リテラル内に含めます。

文字列リテラルに挿入する各項目(変数または定数)は、1組の括弧で囲まれ、先頭に円記号が付きます。 これは簡単な例です-

var varA = 20
let constA = 100
var varC:Float = 20.0

var stringA = "\(varA) times \(constA) is equal to \(varC * 100)"
print( stringA )

上記のコードをコンパイルして実行すると、次の結果が生成されます-

20 times 100 is equal to 2000.0

文字列連結

+演算子を使用して、2つの文字列または文字列と文字、または2つの文字を連結できます。 これは簡単な例です-

let constA = "Hello,"
let constB = "World!"

var stringA = constA + constB
print( stringA )

上記のコードをコンパイルして実行すると、次の結果が生成されます-

Hello,World!

ストリングの長さ

Swift 4の文字列には length プロパティはありませんが、グローバルcount()関数を使用して文字列の文字数をカウントできます。 これは簡単な例です-

var varA = "Hello, Swift 4!"

print( "\(varA), length is \((varA.count))" )

上記のコードをコンパイルして実行すると、次の結果が生成されます-

Hello, Swift 4!, length is 15

文字列比較

==演算子を使用して、2つの文字列変数または定数を比較できます。 これは簡単な例です-

var varA = "Hello, Swift 4!"
var varB = "Hello, World!"

if varA == varB {
   print( "\(varA) and \(varB) are equal" )
} else {
   print( "\(varA) and \(varB) are not equal" )
}

上記のコードをコンパイルして実行すると、次の結果が生成されます-

Hello, Swift 4! and Hello, World! are not equal

文字列の反復

文字列は、Swift 4の値のコレクションであるため、ループを使用して文字列を反復処理できます。 −

for chars in "ThisString" {
   print(chars, terminator: " ")
}

上記のコードをコンパイルして実行すると、次の結果が生成されます-

T h i s S t r i n g

Unicode文字列

次の例に示すように、utf8およびutf16プロパティを反復処理することにより、文字列のUTF-8およびUTF-16表現にアクセスできます-

var unicodeString = "Dog???"

print("UTF-8 Codes: ")
for code in unicodeString.utf8 {
   print("\(code) ")
}

print("\n")

print("UTF-16 Codes: ")
for code in unicodeString.utf16 {
   print("\(code) ")
}

上記のコードをコンパイルして実行すると、次の結果が生成されます-

UTF-8 Codes:
68
111
103
63
63
63


UTF-16 Codes:
68
111
103
63
63
63

文字列関数と演算子

Swift 4は、文字列に関連するさまざまなメソッドと演算子をサポートしています-

Sr.No Functions/Operators & Purpose
1

isEmpty

文字列が空かどうかを決定するブール値。

2

hasPrefix(prefix: String)

指定されたパラメータ文字列が文字列の接頭辞として存在するかどうかを確認する関数。

3

hasSuffix(suffix: String)

指定されたパラメータ文字列が文字列の接尾辞として存在するかどうかを確認する関数。

4

toInt()

数値の文字列値を整数に変換する関数。

5

count()

文字列内の文字数をカウントするグローバル関数。

6

utf8

文字列のUTF-8表現を返すプロパティ。

7

utf16

文字列のUTF-16表現を返すプロパティ。

8

unicodeScalars

文字列のUnicodeスカラー表現を返すプロパティ。

9

+

2つの文字列、または文字列と文字、または2つの文字を連結する演算子。

10

=* *=

文字列または文字を既存の文字列に追加する演算子。

11

== ==

2つの文字列の等価性を判定する演算子。

12

<

辞書編集比較を実行して、ある文字列が別の文字列よりも小さいかどうかを判断する演算子。

13

startIndex

文字列の開始インデックスで値を取得します。

14

endIndex

文字列の終了インデックスで値を取得します。

15

Indices

インデックスに1つずつアクセスします。 つまり、stringのすべての文字を1つずつ。

16

insert("Value", at: position)

位置に値を挿入します。

17

remove(at: position)

  • removeSubrange(range) *

位置の値を削除するか、文字列から値の範囲を削除します。

18
  • reversed()*

文字列の逆を返します

スイフト-キャラクター

Swiftの*文字*は、データ型 Character によってアドレス指定される単一文字のStringリテラルです。 次の例を見てください。 それは2つの文字定数を使用します-

let char1: Character = "A"
let char2: Character = "B"

print("Value of char1 \(char1)")
print("Value of char2 \(char2)")

上記のコードをコンパイルして実行すると、次の結果が生成されます-

Value of char1 A
Value of char2 B

Character型の変数または定数に複数の文字を保存しようとすると、Swift 4はそれを許可しません。 Swift 4 Playgroundで次の例を入力すると、コンパイル前でもエラーが発生します。

//Following is wrong in Swift 4
let char: Character = "AB"

print("Value of char \(char)")

空の文字変数

空の値を持つ空の文字変数または定数を作成することはできません。 次の構文は不可能です-

//Following is wrong in Swift 4
let char1: Character = ""
var char2: Character = ""

print("Value of char1 \(char1)")
print("Value of char2 \(char2)")

文字列から文字にアクセスする

Swift 4の文字列の説明で説明したように、文字列は指定された順序で文字値のコレクションを表します。 そのため、 for-in ループでその文字列を反復処理することにより、指定された文字列から個々の文字にアクセスできます-

for ch in "Hello" {
   print(ch)
}

上記のコードをコンパイルして実行すると、次の結果が生成されます-

H
e
l
l
o

文字列と文字の連結

次の例は、Swift 4の文字をSwift 4の文字列と連結する方法を示しています。

var varA:String = "Hello "
let varB:Character = "G"

varA.append( varB )

print("Value of varC = \(varA)")

上記のコードをコンパイルして実行すると、次の結果が生成されます-

Value of varC = Hello G

Swift-配列

Swift 4配列は、同じタイプの値の順序付きリストを格納するために使用されます。 Swift 4は厳密なチェックを行うため、誤って配列に間違った型を入力することはできません。

作成された配列を変数に割り当てると、変数は常に変更可能になります。つまり、項目を追加、削除、または変更することで変更できます。ただし、配列を定数に割り当てた場合、その配列は不変であり、サイズと内容は変更できません。

配列の作成

次の初期化構文を使用して、特定のタイプの空の配列を作成できます-

var someArray = [SomeType]()

これは、指定されたサイズa *の配列を作成し、値で初期化する構文です-

var someArray = [SomeType](count: NumbeOfElements, repeatedValue: InitialValue)

次のステートメントを使用して、3つの要素とゼロとしての初期値を持つ Int 型の空の配列を作成できます-

var someInts = [Int](count: 3, repeatedValue: 0)

以下は、3つの要素の配列を作成し、その配列に3つの値を割り当てるためのもう一つの例です-

var someInts:[Int] = [10, 20, 30]

配列へのアクセス

あなたは次のように配列の名前の直後に角括弧内に取得したい値のインデックスを渡す subscript 構文を使用して、配列から値を取得することができます-

var someVar = someArray[index]

ここで、 index は0から始まります。つまり、最初の要素は0のインデックスを使用してアクセスでき、2番目の要素は1のインデックスを使用してアクセスできるということです。 次の例は、配列を作成、初期化、およびアクセスする方法を示しています-

var someInts = [Int](count: 3, repeatedValue: 10)

var someVar = someInts[0]
print( "Value of first element is \(someVar)" )
print( "Value of second element is \(someInts[1])" )
print( "Value of third element is \(someInts[2])" )

上記のコードをコンパイルして実行すると、次の結果が生成されます-

Value of first element is 10
Value of second element is 10
Value of third element is 10

配列の変更

  • append()*メソッドまたは追加の代入演算子(+ =)を使用して、配列の最後に新しいアイテムを追加できます。 次の例を見てください。 ここでは、最初に、空の配列を作成してから、同じ配列に新しい要素を追加します-
var someInts = [Int]()

someInts.append(20)
someInts.append(30)
someInts += [40]

var someVar = someInts[0]

print( "Value of first element is \(someVar)" )
print( "Value of second element is \(someInts[1])" )
print( "Value of third element is \(someInts[2])" )

上記のコードをコンパイルして実行すると、次の結果が生成されます-

Value of first element is 20
Value of second element is 30
Value of third element is 40

あなたは、次の例に示すように、特定のインデックスで新しい値を割り当てることにより、配列の既存の要素を変更することができます-

var someInts = [Int]()

someInts.append(20)
someInts.append(30)
someInts += [40]

//Modify last element
someInts[2] = 50

var someVar = someInts[0]

print( "Value of first element is \(someVar)" )
print( "Value of second element is \(someInts[1])" )
print( "Value of third element is \(someInts[2])" )

上記のコードをコンパイルして実行すると、次の結果が生成されます-

Value of first element is 20
Value of second element is 30
Value of third element is 50

配列の繰り返し

あなたは、次の例に示すように、配列内の値のセット全体を反復するために for-in ループを使用することができます-

var someStrs = [String]()

someStrs.append("Apple")
someStrs.append("Amazon")
someStrs += ["Google"]
for item in someStrs {
   print(item)
}

上記のコードをコンパイルして実行すると、次の結果が生成されます-

Apple
Amazon
Google

次の例に示すように、値とともにアイテムのインデックスを返す* enumerate()*関数を使用できます-

var someStrs = [String]()

someStrs.append("Apple")
someStrs.append("Amazon")
someStrs += ["Google"]

for (index, item) in someStrs.enumerated() {
   print("Value at index = \(index) is \(item)")
}

上記のコードをコンパイルして実行すると、次の結果が生成されます-

Value at index = 0 is Apple
Value at index = 1 is Amazon
Value at index = 2 is Google

2つの配列を追加する

あなたは、次のように2つの配列からの値の組み合わせで新しい配列を生成する同じタイプの2つの配列を追加するために、加算演算子(+)を使用することができます-

var intsA = [Int](count:2, repeatedValue: 2)
var intsB = [Int](count:3, repeatedValue: 1)

var intsC = intsA + intsB
for item in intsC {
   print(item)
}

上記のコードをコンパイルして実行すると、次の結果が生成されます-

2
2
1
1
1

countプロパティ

あなたは、配列の読み取り専用*カウント*プロパティを使用して、以下に示す配列内のアイテムの数を調べることができます-

var intsA = [Int](count:2, repeatedValue: 2)
var intsB = [Int](count:3, repeatedValue: 1)

var intsC = intsA + intsB

print("Total items in intsA = \(intsA.count)")
print("Total items in intsB = \(intsB.count)")
print("Total items in intsC = \(intsC.count)")

上記のコードをコンパイルして実行すると、次の結果が生成されます-

Total items in intsA = 2
Total items in intsB = 3
Total items in intsC = 5

空のプロパティ

以下に示すように、配列の読み取り専用*空*プロパティを使用して、配列が空かどうかを調べることができます-

var intsA = [Int](count:2, repeatedValue: 2)
var intsB = [Int](count:3, repeatedValue: 1)
var intsC = [Int]()

print("intsA.isEmpty = \(intsA.isEmpty)")
print("intsB.isEmpty = \(intsB.isEmpty)")
print("intsC.isEmpty = \(intsC.isEmpty)")

上記のコードをコンパイルして実行すると、次の結果が生成されます-

intsA.isEmpty = false
intsB.isEmpty = false
intsC.isEmpty = true

スイフト-セット

Swift 4 sets は同じ型の異なる値を格納するために使用されますが、配列のように明確な順序はありません。

要素の順序が問題にならない場合、または重複する値がないことを確認したい場合は、配列の代わりにセットを使用できます。 (セットでは個別の値のみが許可されます。)

タイプは、セットに格納するためにハッシュ可能でなければなりません。 ハッシュ値は、等しいオブジェクトに対して等しいInt値です。 たとえば、x == yの場合、 x.hashvalue == y.hashvalue です。

基本的なすべての迅速な値は、デフォルトでハッシュ可能なタイプであり、設定値として使用できます。

セットを作成する

次の初期化構文を使用して、特定のタイプの空のセットを作成できます-

var someSet = Set<Character>()    //Character can be replaced by data type of set.

セットへのアクセスと変更

あなたはそのメソッドとプロパティを使用してセットにアクセスまたは変更することができます-

「count」メソッドを使用して、セット内の要素の数を表示できます。

someSet.count       //prints the number of elements

「挿入」メソッドを使用して、値をセットに挿入できます。

someSet.insert("c")  //adds the element to Set.

同様に、isEmptyを使用して、setが空かどうかを確認できます。

someSet.isEmpty      //returns true or false depending on the set Elements.

「remove」メソッドを使用して、セット内の値を削除できます。

someSet.remove("c")    //removes a element , removeAll() can be used to remove all elements

「含む」メソッドを使用して、セット内の値の存在を確認できます。

someSet.contains("c")    //to check if set contains this value.

セットの繰り返し

あなたはfor-inループを使用してセットを反復処理できます-

for items in someSet {
   print(someSet)
}

//Swift sets are not in an ordered way, to iterate over a set in ordered way use

for items in someSet.sorted() {
   print(someSet)
}

集合演算の実行

迅速なセットに対して基本的なセット操作を実行できます。

以下は、集合演算を実行するための方法です-

  • 交差点
  • 連合
  • 引き算
let evens: Set = [10,12,14,16,18]
let odds: Set = [5,7,9,11,13]
let primes = [2,3,5,7]
odds.union(evens).sorted()
//[5,7,9,10,11,12,13,14,16,18]
odds.intersection(evens).sorted()
//[]
odds.subtracting(primes).sorted()
//[9, 11, 13]

Swift-辞書

Swift 4 *辞書*は、同じタイプの値の順序付けられていないリストを保存するために使用されます。 Swift 4は厳密なチェックを行うため、誤って誤ったタイプを辞書に入力することはありません。

Swift 4ディクショナリは、 key と呼ばれる一意の識別子を使用して、後で同じキーを介して参照および検索できる値を格納します。 配列内のアイテムとは異なり、*辞書*内のアイテムには順序が指定されていません。 識別子に基づいて値を検索する必要がある場合は、*辞書*を使用できます。

辞書キーは、整数または制限なしの文字列のいずれでもかまいませんが、辞書内で一意である必要があります。

作成したディクショナリを変数に割り当てると、常に可変になります。つまり、アイテムを追加、削除、または変更することで変更できます。 ただし、辞書を定数に割り当てた場合、その辞書は不変であり、そのサイズと内容は変更できません。

辞書を作成する

次の初期化構文を使用して、特定のタイプの空の辞書を作成できます-

var someDict = [KeyType: ValueType]()

次の単純な構文を使用して、キーがInt型になり、関連する値が文字列になる空の辞書を作成できます-

var someDict = [Int: String]()

これは、与えられた値のセットから辞書を作成する例です-

var someDict:[Int:String] = [1:"One", 2:"Two", 3:"Three"]

シーケンスベースの初期化

Swift 4では、配列(キーと値のペア)から辞書を作成できます。

var cities = [“Delhi”,”Bangalore”,”Hyderabad”]

次の単純な構文を使用して、キーがInt型になり、関連する値が文字列になる空の辞書を作成できます-

var Distance = [2000,10, 620]

これは、与えられた値のセットから辞書を作成する例です-

let cityDistanceDict = Dictionary(uniqueKeysWithValues: zip(cities, Distance))

上記のコード行は、都市をキー、距離を値として辞書を作成します-

フィルタリング

Swift 4では、辞書から値をフィルタリングできます。

var closeCities = cityDistanceDict.filter { $0.value < 1000 }

上記のコードを実行すると、closeCities辞書が作成されます。

["Bangalore" : 10 , "Hyderabad" : 620]

辞書のグループ化

Swift 4では、辞書値のグループ化を作成できます。

var cities = ["Delhi","Bangalore","Hyderabad","Dehradun","Bihar"]

次の簡単な構文を使用して、最初のアルファベットに従って辞書の値をグループ化できます。

var GroupedCities = Dictionary(grouping: cities ) { $0.first! }

上記のコードの結果は次のようになります

["D" :["Delhi","Dehradun"], "B" : ["Bengaluru","Bihar"], "H" : ["Hyderabad"]]

辞書へのアクセス

あなたは、次のように辞書の名前の直後に角括弧内に取得したい値のキーを渡す添字構文を使用して、辞書から値を取得することができます-

var someVar = someDict[key]

辞書から値を作成、初期化、およびアクセスするには、次の例をチェックしましょう-

var someDict:[Int:String] = [1:"One", 2:"Two", 3:"Three"]
var someVar = someDict[1]

print( "Value of key = 1 is \(someVar)" )
print( "Value of key = 2 is \(someDict[2])" )
print( "Value of key = 3 is \(someDict[3])" )

上記のコードをコンパイルして実行すると、次の結果が生成されます-

Value of key = 1 is Optional("One")
Value of key = 2 is Optional("Two")
Value of key = 3 is Optional("Three")

辞書の変更

  • updateValue(forKey:)*メソッドを使用して、既存の値を辞書の特定のキーに追加できます。 このメソッドは、ディクショナリの値タイプのオプションの値を返します。 これは簡単な例です-
var someDict:[Int:String] = [1:"One", 2:"Two", 3:"Three"]
var oldVal = someDict.updateValue("New value of one", forKey: 1)
var someVar = someDict[1]

print( "Old value of key = 1 is \(oldVal)" )
print( "Value of key = 1 is \(someVar)" )
print( "Value of key = 2 is \(someDict[2])" )
print( "Value of key = 3 is \(someDict[3])" )

上記のコードをコンパイルして実行すると、次の結果が生成されます-

Old value of key = 1 is Optional("One")
Value of key = 1 is Optional("New value of one")
Value of key = 2 is Optional("Two")
Value of key = 3 is Optional("Three")

次の例に示すように、特定のキーに新しい値を割り当てることにより、辞書の既存の要素を変更できます-

var someDict:[Int:String] = [1:"One", 2:"Two", 3:"Three"]
var oldVal = someDict[1]
someDict[1] = "New value of one"
var someVar = someDict[1]

print( "Old value of key = 1 is \(oldVal)" )
print( "Value of key = 1 is \(someVar)" )
print( "Value of key = 2 is \(someDict[2])" )
print( "Value of key = 3 is \(someDict[3])" )

上記のコードをコンパイルして実行すると、次の結果が生成されます-

Old value of key = 1 is Optional("One")
Value of key = 1 is Optional("New value of one")
Value of key = 2 is Optional("Two")
Value of key = 3 is Optional("Three")

キーと値のペアを削除

  • removeValueForKey()*メソッドを使用して、キーと値のペアを辞書から削除できます。 このメソッドは、キーと値のペアが存在する場合は削除し、削除した値を返します。値が存在しない場合はnilを返します。 これは簡単な例です-
var someDict:[Int:String] = [1:"One", 2:"Two", 3:"Three"]
var removedValue = someDict.removeValue(forKey: 2)

print( "Value of key = 1 is \(someDict[1])" )
print( "Value of key = 2 is \(someDict[2])" )
print( "Value of key = 3 is \(someDict[3])" )

上記のコードをコンパイルして実行すると、次の結果が生成されます-

Value of key = 1 is Optional("One")
Value of key = 2 is nil
Value of key = 3 is Optional("Three")

また、添え字構文を使用して、そのキーに nil の値を割り当てることにより、辞書からキーと値のペアを削除することもできます。 これは簡単な例です-

var someDict:[Int:String] = [1:"One", 2:"Two", 3:"Three"]

someDict[2] = nil

print( "Value of key = 1 is \(someDict[1])" )
print( "Value of key = 2 is \(someDict[2])" )
print( "Value of key = 3 is \(someDict[3])" )

上記のコードをコンパイルして実行すると、次の結果が生成されます-

Value of key = 1 is Optional("One")
Value of key = 2 is nil
Value of key = 3 is Optional("Three")

辞書の繰り返し

次の例に示すように、辞書のキーと値のペアのセット全体を反復処理するために、 for-in ループを使用できます-

var someDict:[Int:String] = [1:"One", 2:"Two", 3:"Three"]

for (index, keyValue) in someDict.enumerated() {
   print("Dictionary key \(index) - Dictionary value \(keyValue)")
}

上記のコードをコンパイルして実行すると、次の結果が生成されます-

Dictionary key 2 - Dictionary value Two
Dictionary key 3 - Dictionary value Three
Dictionary key 1 - Dictionary value One

以下の例に示すように、アイテムのインデックスとその(key、value)ペアを返す* enumerate()*関数を使用できます-

var someDict:[Int:String] = [1:"One", 2:"Two", 3:"Three"]
for (key, value) in someDict.enumerated() {
   print("Dictionary key \(key) - Dictionary value \(value)")
}

上記のコードをコンパイルして実行すると、次の結果が生成されます-

Dictionary key 0 - Dictionary value (key: 2, value: "Two")
Dictionary key 1 - Dictionary value (key: 3, value: "Three")
Dictionary key 2 - Dictionary value (key: 1, value: "One")

配列に変換

特定の辞書からキーと値のペアのリストを抽出して、キーと値の両方に対して個別の配列を作成できます。 ここに例があります-

var someDict:[Int:String] = [1:"One", 2:"Two", 3:"Three"]

let dictKeys = [Int](someDict.keys)
let dictValues = [String](someDict.values)

print("Print Dictionary Keys")

for (key) in dictKeys {
   print("\(key)")
}
print("Print Dictionary Values")

for (value) in dictValues {
   print("\(value)")
}

上記のコードをコンパイルして実行すると、次の結果が生成されます-

Print Dictionary Keys
2
3
1
Print Dictionary Values
Two
Three
One

countプロパティ

以下に示すように、辞書の読み取り専用 count プロパティを使用して、辞書内のアイテムの数を調べることができます-

var someDict1:[Int:String] = [1:"One", 2:"Two", 3:"Three"]
var someDict2:[Int:String] = [4:"Four", 5:"Five"]

print("Total items in someDict1 = \(someDict1.count)")
print("Total items in someDict2 = \(someDict2.count)")

上記のコードをコンパイルして実行すると、次の結果が生成されます-

Total items in someDict1 = 3
Total items in someDict2 = 2

空のプロパティ

次のように、辞書の読み取り専用 empty プロパティを使用して、辞書が空かどうかを確認できます-

var someDict1:[Int:String] = [1:"One", 2:"Two", 3:"Three"]
var someDict2:[Int:String] = [4:"Four", 5:"Five"]
var someDict3:[Int:String] = [Int:String]()

print("someDict1 = \(someDict1.isEmpty)")
print("someDict2 = \(someDict2.isEmpty)")
print("someDict3 = \(someDict3.isEmpty)")

上記のコードをコンパイルして実行すると、次の結果が生成されます-

someDict1 = false
someDict2 = false
someDict3 = true

Swift-関数

関数は、特定のタスクを実行するためにまとめられた一連のステートメントです。 Swift 4の関数は、単純なC関数のように単純なものから、Objective C言語の関数のように複雑なものまであります。 関数呼び出し内でローカルおよびグローバルのパラメーター値を渡すことができます。

  • 関数宣言-コンパイラーに関数の名前、戻り値の型、およびパラメーターについて通知します。
  • 関数の定義-関数の実際の本体を提供します。

Swift 4の関数には、パラメーター型とその戻り値の型が含まれています。

関数定義

Swift 4では、関数は「func」キーワードによって定義されます。 関数が新しく定義されると、関数への入力「パラメーター」として1つまたは複数の値を取り、本体の関数を処理し、値を出力「戻り型」として関数に返します。

すべての関数には関数名があり、関数が実行するタスクを説明しています。 関数を使用するには、その関数をその名前で「呼び出し」、関数のパラメーターのタイプに一致する入力値(引数)を渡します。 関数パラメーターは「タプル」とも呼ばれます。

関数の引数は、常に関数のパラメーターリストと同じ順序で指定する必要があり、戻り値の後には→が続きます。

構文

func funcname(Parameters) -> returntype {
   Statement1
   Statement2
   ---
   Statement N
   return parameters
}

次のコードを見てください。 学生の名前は、関数 'student’内で宣言された文字列データ型として宣言され、関数が呼び出されると、学生の名前が返されます。

func student(name: String) -> String {
   return name
}

print(student(name: "First Program"))
print(student(name: "About Functions"))

プレイグラウンドを使用して上記のプログラムを実行すると、次の結果が得られます-

First Program
About Functions

関数を呼び出す

たとえば、関数名が「display」の関数が整数データ型を保持する引数「no1」で初期化される数値を表示することを検討するために、「display」と呼ばれる関数を定義したとします。 次に、引数 'no1’が引数 'a’に割り当てられ、以降は同じデータ型の整数を指します。 これで、引数 'a’が関数に返されます。 ここで、display()関数は整数値を保持し、関数が呼び出されるたびに整数値を返します。

func display(no1: Int) -> Int {
   let a = no1
   return a
}

print(display(no1: 100))
print(display(no1: 200))

プレイグラウンドを使用して上記のプログラムを実行すると、次の結果が得られます-

100
200

パラメータと戻り値

Swift 4は、単純な値から複雑な値まで、柔軟な関数パラメーターとその戻り値を提供します。 CおよびObjective Cの関数と同様に、Swift 4の関数もいくつかの形式を取ります。

パラメータ付き関数

関数にアクセスするには、そのパラメーター値を関数の本体に渡します。 関数内でタプルとして単一から複数のパラメーター値を渡すことができます。

func mult(no1: Int, no2: Int) -> Int {
   return no1*no2
}

print(mult(no1: 2, no2: 20))
print(mult(no1: 3, no2: 15))
print(mult(no1: 4, no2: 30))

プレイグラウンドを使用して上記のプログラムを実行すると、次の結果が得られます-

40
45
120

パラメータなしの関数

パラメータのない関数もあります。

構文

func funcname() -> datatype {
   return datatype
}

以下は、パラメータなしの関数を持つ例です-

func votersname() -> String {
   return "Alice"
}
print(votersname())

プレイグラウンドを使用して上記のプログラムを実行すると、次の結果が得られます-

Alice

戻り値を持つ関数

関数は、文字列、整数、および浮動小数点データ型の値を戻り値の型として返すためにも使用されます。 与えられた配列の最大数と最小数を見つけるために、「ls」は大小の整数データ型で宣言されています。

配列は整数値を保持するために初期化されます。 次に、配列が処理され、配列内のすべての値が読み取られ、前の値と比較されます。 値が前の値よりも小さい場合は「small」引数に格納され、それ以外の場合は「large」引数に格納され、関数を呼び出して値が返されます。

func ls(array: [Int]) -> (large: Int, small: Int) {
   var lar = array[0]
   var sma = array[0]

   for i in array[1..<array.count] {
      if i < sma {
         sma = i
      } else if i > lar {
         lar = i
      }
   }
   return (lar, sma)
}

let num = ls(array: [40,12,-5,78,98])
print("Largest number is: \(num.large) and smallest number is: \(num.small)")

プレイグラウンドを使用して上記のプログラムを実行すると、次の結果が得られます-

Largest number is: 98 and smallest number is: -5

戻り値のない関数

一部の関数は、戻り値なしで関数内で宣言された引数を持つ場合があります。 次のプログラムは、 a および b をs​​um()関数の引数として宣言します。 関数自体の内部で、引数 a および b の値は、関数呼び出しsum()を呼び出すことで渡され、その値が出力されるため、戻り値が削除されます。

func sum(a: Int, b: Int) {
   let a = a + b
   let b = a - b
   print(a, b)
}

sum(a: 20, b: 10)
sum(a: 40, b: 10)
sum(a: 24, b: 6)

プレイグラウンドを使用して上記のプログラムを実行すると、次の結果が得られます-

30 20
50 40
30 24

オプションの戻り値型を持つ関数

Swift 4は、安全対策を導入することで問題を取り除くための「オプション」機能を導入しています。 例えば、関数値が整数として返されるタイプを宣言しているが、関数が文字列値またはnil値を返すとどうなるかを考えてみましょう。 その場合、コンパイラはエラー値を返します。 これらの問題を取り除くために「オプション」が導入されています。

オプションの関数は、「値」と「nil」の2つの形式を取ります。 キーの予約文字「?」とともに「オプション」に言及します。タプルが値を返すか、nil値を返すかを確認します。

func minMax(array: [Int]) -> (min: Int, max: Int)? {
   if array.isEmpty { return nil }
   var currentMin = array[0]
   var currentMax = array[0]

   for value in array[1..<array.count] {
      if value < currentMin {
         currentMin = value
      } else if value > currentMax {
         currentMax = value
      }
   }
   return (currentMin, currentMax)
}

if let bounds = minMax(array: [8, -6, 2, 109, 3, 71]) {
   print("min is \(bounds.min) and max is \(bounds.max)")
}

プレイグラウンドを使用して上記のプログラムを実行すると、次の結果が得られます-

min is -6 and max is 109

「オプション」は、「nil」値またはガベージ値をチェックするために使用されるため、デバッグに多くの時間を消費し、ユーザーにとってコードを効率的かつ読みやすくします。

関数ローカルと外部パラメーター名

ローカルパラメータ名

ローカルパラメータ名は、関数内でのみアクセスされます。

func sample(number: Int) {
   print(number)
}

ここで、 func サンプル引数番号は、関数sample()によって内部的にアクセスされるため、内部変数として宣言されます。 ここで、「番号」はローカル変数として宣言されていますが、変数への参照は次のステートメントで関数の外部で行われます-

func sample(number: Int) {
   print(number)
}

sample(number: 1)
sample(number: 2)
sample(number: 3)

プレイグラウンドを使用して上記のプログラムを実行すると、次の結果が得られます-

1
2
3

外部パラメーター名

外部パラメーター名を使用すると、目的をより明確にするために関数パラメーターに名前を付けることができます。 以下の例では、2つの関数パラメータに名前を付けて、その関数を次のように呼び出すことができます-

func pow(firstArg a: Int, secondArg b: Int) -> Int {
   var res = a
   for _ in 1..<b {
      res = res * a
   }
   print(res)
   return res
}

pow(firstArg:5, secondArg:3)

プレイグラウンドを使用して上記のプログラムを実行すると、次の結果が得られます-

125

可変パラメータ

複数の引数を使用して関数を定義する場合、メンバーを「変数」パラメーターとして宣言できます。 パラメーターは、パラメーター名の後に(…)によって可変引数として指定できます。

func vari<N>(members: N...){
   for i in members {
      print(i)
   }
}

vari(members: 4,3,5)
vari(members: 4.5, 3.1, 5.6)
vari(members: "Swift 4", "Enumerations", "Closures")

プレイグラウンドを使用して上記のプログラムを実行すると、次の結果が得られます-

4
3
5
4.5
3.1
5.6
Swift 4
Enumerations
Closures

定数、変数、I/Oパラメーター

デフォルトでは、関数はパラメーターを「定数」と見なしますが、ユーザーは関数の引数を変数として宣言することもできます。 「let」キーワードを使用して定数パラメーターを宣言し、変数パラメーターを「var」キーワードで定義することはすでに説明しました。

Swift 4のI/Oパラメーターは、関数呼び出し後に値が変更されてもパラメーター値を保持する機能を提供します。 関数パラメーター定義の最初に、メンバー値を保持するために「inout」キーワードが宣言されます。

値は関数に「in」で渡され、その値は関数本体によってアクセスおよび変更され、元の引数を変更するために関数の「out」に戻されるため、キーワード「inout」を派生させます。

変数は、値だけが関数の内外で変更されるため、in-outパラメーターの引数としてのみ渡されます。 したがって、文字列とリテラルを入出力パラメータとして宣言する必要はありません。 変数名の前の「&」は、引数を入出力パラメーターに渡していることを示します。

func temp(a1: inout Int, b1: inout Int) {
   let t = a1
   a1 = b1
   b1 = t
}

var no = 2
var co = 10
temp(a1: &no, b1: &co)
print("Swapped values are \(no), \(co)")

プレイグラウンドを使用して上記のプログラムを実行すると、次の結果が得られます-

Swapped values are 10, 2

関数の種類とその使用法

各パラメーターは、入力パラメーターを考慮して特定の機能に従い、目的の結果を出力します。

func inputs(no1: Int, no2: Int) -> Int {
   return no1/no2
}

以下は例です-

func inputs(no1: Int, no2: Int) -> Int {
   return no1/no2
}

print(inputs(no1: 20, no2: 10))
print(inputs(no1: 36, no2: 6))

プレイグラウンドを使用して上記のプログラムを実行すると、次の結果が得られます-

2
6

ここでは、関数は整数データ型として2つの引数 no1 および no2 で初期化され、その戻り値の型も 'int’として宣言されています

Func inputstr(name: String) -> String {
   return name
}

ここでは、関数は string データ型として宣言されています。

関数には void データ型もあり、そのような関数は何も返しません。

func inputstr() {
   print("Swift 4 Functions")
   print("Types and its Usage")
}
inputstr()

プレイグラウンドを使用して上記のプログラムを実行すると、次の結果が得られます-

Swift 4 Functions
Types and its Usage

上記の関数は、引数も戻り値もないvoid関数として宣言されています。

関数型を使用する

関数は、最初に整数、フロート、または文字列型の引数で渡され、次に定数または変数として関数に渡されます。これについては以下で説明します。

var addition: (Int, Int) -> Int = sum

ここで、sumは 'a’および 'b’整数変数を持つ関数名であり、関数名追加の変数として宣言されています。 これ以降、加算関数と合計関数の両方に、整数データ型として宣言された同じ数の引数があり、参照として整数値も返します。

func sum(a: Int, b: Int) -> Int {
   return a + b
}
var addition: (Int, Int) -> Int = sum
print("Result: \(addition(40, 89))")

プレイグラウンドを使用して上記のプログラムを実行すると、次の結果が得られます-

Result: 129

パラメータ型および戻り値型としての関数型

関数自体をパラメーター型として別の関数に渡すこともできます。

func sum(a: Int, b: Int) -> Int {
   return a + b
}
var addition: (Int, Int) -> Int = sum
print("Result: \(addition(40, 89))")

func another(addition: (Int, Int) -> Int, a: Int, b: Int) {
   print("Result: \(addition(a, b))")
}
another(sum, 10, 20)

プレイグラウンドを使用して上記のプログラムを実行すると、次の結果が得られます-

Result: 129
Result: 30

入れ子関数

ネストされた関数は、内部関数を呼び出すことにより外部関数を呼び出す機能を提供します。

func calcDecrement(forDecrement total: Int) -> () -> Int {
   var overallDecrement = 0
   func decrementer() -> Int {
      overallDecrement -= total
      return overallDecrement
   }
   return decrementer
}

let decrem = calcDecrement(forDecrement: 30)
print(decrem())

プレイグラウンドを使用して上記のプログラムを実行すると、次の結果が得られます-

-30

スイフト-クロージャー

Swift 4のクロージャーは、ブロックとして編成され、C言語やObjective C言語などの任意の場所で呼び出される自己完結型関数のクロージャーに似ています。 関数内で定義された定数および変数参照はキャプチャーされ、クロージャーに保存されます。 関数はクロージャの特別なケースと見なされ、次の3つの形式を取ります-

Global Functions Nested Functions Closure Expressions
Have a name. Do not capture any values Have a name. Capture values from enclosing function Unnamed Closures capture values from the adjacent blocks

Swift 4言語のクロージャー式は、鮮明で最適化された軽量の構文スタイルを含んでいます。

  • コンテキストからパラメーターと戻り値の型を推測します。
  • 単一式クロージャーからの暗黙的な戻り。
  • 略式の引数名と
  • 末尾のクロージャー構文

構文

以下は、パラメータを受け入れてデータ型を返すクロージャを定義するための一般的な構文です-

{
   (parameters) −> return type in
   statements
}

以下は簡単な例です-

let studname = { print("Welcome to Swift Closures") }
studname()

プレイグラウンドを使用して上記のプログラムを実行すると、次の結果が得られます-

Welcome to Swift Closures

次のクロージャは2つのパラメータを受け入れ、Bool値を返します-

{
   (Int, Int) −> Bool in
   Statement1
   Statement 2
   ---
   Statement n
}

以下は簡単な例です-

let divide = {
   (val1: Int, val2: Int) -> Int in
   return val1/val2
}

let result = divide(200, 20)
print (result)

プレイグラウンドを使用して上記のプログラムを実行すると、次の結果が得られます-

10

クロージャーの式

入れ子関数は、コードのブロックに名前を付けて定義する便利な方法を提供します。 関数宣言全体を表す代わりに、より短い関数を示すために名前の構成体が使用されます。 関数を明確な簡潔なステートメントで表現し、焦点を絞った構文でクロージャー式を使用して実現します。

昇順プログラム

文字列のソートは、標準ライブラリですでに利用可能なSwift 4sキー予約関数「sorted」によって実現されます。 この関数は、指定された文字列を昇順で並べ替え、古い配列で指定されたサイズとデータ型と同じサイズの新しい配列の要素を返します。 古い配列は同じままです。

2つの引数は、ソートされた関数内で表されます-

  • 配列として表される既知のタイプの値。
  • 配列の内容(Int、Int)およびブール値(Bool)を返します。配列が適切にソートされている場合はtrue値を返し、そうでない場合はfalseを返します。

入力文字列を持つ通常の関数が書き込まれ、ソートされた関数に渡されて、以下に示す新しい配列にソートされた文字列を取得します-

func ascend(s1: String, s2: String) -> Bool {
   return s1 > s2
}

let stringcmp = ascend(s1: "Swift 4", s2: "great")
print (stringcmp)

プレイグラウンドを使用して上記のプログラムを実行すると、次の結果が得られます-

true

アイスクリーム用にソートされる初期配列は、「Swift 4」および「great」として指定されています。 配列を並べ替える関数は文字列データ型として宣言され、その戻り値の型はブール値として示されます。 両方の文字列が比較され、昇順で並べ替えられ、新しい配列に格納されます。 ソートが正常に実行された場合、関数はtrue値を返します。それ以外の場合、falseを返します。

クロージャー式の構文は次を使用します-

  • 定数パラメータ、
  • 可変パラメーター、および
  • 入力パラメータ。

クロージャー式はデフォルト値をサポートしていませんでした。 可変引数とタプルは、パラメーターの型と戻り値の型としても使用できます。

let sum = {
   (no1: Int, no2: Int) -> Int in
   return no1 + no2
}

let digits = sum(10, 20)
print(digits)

プレイグラウンドを使用して上記のプログラムを実行すると、次の結果が得られます-

30

関数ステートメントで言及されているパラメーターと戻り値の宣言は、「in」キーワードを使用したインラインクロージャー式関数でも表すことができます。 パラメータと戻り値の型を宣言すると、「in」キーワードを使用してクロージャの本体を示します。

単一式の暗黙的な戻り値

ここでは、ソートされた関数の2番目の引数の関数型により、クロージャーがBool値を返す必要があることが明確になります。 クロージャーの本体にはBool値を返す単一の式(s1> s2)が含まれているため、あいまいさはなく、returnキーワードは省略できます。

式クロージャーで単一式ステートメントを返すには、宣言部分で「return」キーワードを省略します。

var count:[Int] = [5, 10, -6, 75, 20]
let descending = count.sorted(by: { n1, n2 in n1 > n2 })
let ascending = count.sorted(by: { n1, n2 in n1 < n2 })

print(descending)
print(ascending)

プレイグラウンドを使用して上記のプログラムを実行すると、次の結果が得られます-

[75, 20, 10, 5, -6]
[-6, 5, 10, 20, 75]

ステートメント自体は、string1がstring 2よりも大きい場合はtrueを返し、そうでない場合はfalseなので、returnステートメントはここでは省略されることを明確に定義しています。

既知の型の閉鎖

2つの数字の追加を検討してください。 加算により整数データ型が返されることがわかっています。 したがって、既知の型クロージャは次のように宣言されます-

let sub = {
   (no1: Int, no2: Int) -> Int in
   return no1 - no2
}

let digits = sub(10, 20)
print(digits)

プレイグラウンドを使用して上記のプログラムを実行すると、次の結果が得られます-

-10

短縮形の引数名をクロージャーとして宣言する

Swift 4はインラインクロージャーに省略形の引数名を自動的に提供します。これを使用して、$ 0、$ 1、$ 2などの名前でクロージャーの引数の値を参照できます。

var shorthand: (String, String) -> String
shorthand = { $1 }
print(shorthand("100", "200"))

ここで、$ 0と$ 1はクロージャーの最初と2番目のString引数を参照します。

プレイグラウンドを使用して上記のプログラムを実行すると、次の結果が得られます-

200

Swift 4は、$ 0、$ 1、$ 2 --- $ nを表すことにより、ユーザーがインラインクロージャーを短縮形の引数名として表すことを容易にします。

クロージャー式内の省略形の引数名を表す場合、定義セクションではクロージャー引数リストは省略されます。 関数のタイプに基づいて、短縮形の引数名が導出されます。 省略形の引数は式の本文で定義されているため、「in」キーワードは省略されます。

演算子関数としてのクロージャー

Swift 4は、クロージャーとしてオペレーター機能を提供するだけで、メンバーにアクセスする簡単な方法を提供します。 前の例では、キーワード「Bool」を使用して、文字列が等しい場合に「true」を返し、そうでない場合は「false」を返します。

式は、クロージャーの演算子関数によってさらに簡単になります-

let numb = [98, -20, -30, 42, 18, 35]
var sortedNumbers = numb.sorted ({
   (left: Int, right: Int) -> Bool in
   return left < right
})

let asc = numb.sorted(<)
print(asc)

プレイグラウンドを使用して上記のプログラムを実行すると、次の結果が得られます-

[-30, -20, 18, 35, 42, 98]

トレーラーとしての閉鎖

関数の最後の引数をクロージャー式に渡すことは、 'Trailing Closures’を使用して宣言されます。 関数()の外側に\ {}を使用して記述されています。 関数を単一行にインラインで書き込むことができない場合に使用する必要があります。

reversed = sorted(names) { $0 > $1}

ここで、\ {$ 0> $ 1}は、外部(名前)で宣言された末尾のクロージャーとして表されます。

import Foundation
var letters = ["North", "East", "West", "South"]

let twoletters = letters.map({
   (state: String) -> String in
   return state.substringToIndex(advance(state.startIndex, 2)).uppercaseString
})

let stletters = letters.map() {
   $0.substringToIndex(advance($0.startIndex, 2)).uppercaseString
}
print(stletters)

プレイグラウンドを使用して上記のプログラムを実行すると、次の結果が得られます-

[NO, EA, WE, SO]

値と参照タイプのキャプチャ

Swift 4では、クロージャーを使用して定数と変数値をキャプチャします。 さらに、変数が存在しなくても、クロージャー本体内のこれらの定数および変数の値を参照および変更します。

定数と変数の値を取得するには、他の関数の本体に関数を記述してネストされた関数を使用します。

ネストされた関数はキャプチャします-

  • 外部関数の引数。
  • Outer関数内で定義された定数と変数をキャプチャします。

Swift 4では、定数または変数が関数内で宣言されると、その変数への参照もクロージャーによって自動的に作成されます。 また、次のように同じクロージャとして3つ以上の変数を参照する機能を提供します-

let decrem = calcDecrement(forDecrement: 18)
decrem()

ここで、 oneDecrement およびDecrement変数は、どちらもクロージャー参照として同じメモリブロックを指します。

func calcDecrement(forDecrement total: Int) -> () -> Int {
   var overallDecrement = 100
   func decrementer() -> Int {
      overallDecrement -= total
      print(overallDecrement)
      return overallDecrement
   }
   return decrementer
}

let decrem = calcDecrement(forDecrement: 18)
decrem()
decrem()
decrem()

プレイグラウンドを使用して上記のプログラムを実行すると、次の結果が得られます-

82
64
46

外部関数calcDecrementが呼び出されるたびに、decrementer()関数が呼び出され、値が18減分され、外部関数calcDecrementを使用して結果が返されます。 ここで、calcDecrementはクロージャーとして機能します。

関数decrementer()には引数がありませんが、デフォルトでは、クロージャは既存の値をキャプチャすることで変数 'overallDecrement’および 'total’を参照します。 指定された変数の値のコピーは、新しいdecrementer()関数で保存されます。 Swift 4は、変数が使用されていないときにメモリ空間の割り当てと割り当て解除を行うことにより、メモリ管理機能を処理します。

Swift-列挙

列挙は、関連する値のセットで構成されるユーザー定義のデータ型です。 キーワード enum は、列挙データ型を定義するために使用されます。

列挙機能

Swift 4の列挙も、CおよびObjective Cの構造に似ています。

  • クラスで宣言され、その値はそのクラスのインスタンスを通じてアクセスされます。
  • 初期メンバー値は、列挙型の初期化子を使用して定義されます。
  • 標準のプロトコル機能を確保することにより、その機能も拡張されています。

構文

列挙型は列挙型キーワードで導入され、その定義全体を中括弧のペア内に配置します-

enum enumname {
  //enumeration values are described here
}

たとえば、次のように曜日の列挙を定義することができます-

enum DaysofaWeek {
   case Sunday
   case Monday
   ---
   case Saturday
}

enum names {
   case Swift
   case Closures
}

var lang = names.Closures
lang = .Closures

switch lang {
   case .Swift:
      print("Welcome to Swift")
   case .Closures:
      print("Welcome to Closures")
   default:
      print("Introduction")
}

プレイグラウンドを使用して上記のプログラムを実行すると、次の結果が得られます-

Welcome to Closures

Swift 4列挙は、CやObjective Cのようなデフォルト値をメンバーに割り当てません。 代わりに、メンバーは列挙名によって明示的に定義されます。 列挙名は大文字で始める必要があります(例:enum DaysofaWeek)。

var weekDay = DaysofaWeek.Sunday

ここでは、列挙名「DaysofaWeek」が変数weekday.Sundayに割り当てられています。 データ型が日曜日に属することは、その特定のクラスの後続の列挙型メンバーに割り当てられることをコンパイラーに通知します。 列挙メンバーデータ型が定義されると、値と追加の計算を渡すことでメンバーにアクセスできます。

Switchステートメントを使用した列挙

Swift 4の「Switch」ステートメントも、マルチウェイ選択に従います。 指定された条件に基づいて特定の時間にアクセスされる変数は1つだけです。 switchステートメントのデフォルトケースは、未指定のケースをトラップするために使用されます。

enum Climate {
   case India
   case America
   case Africa
   case Australia
}

var season = Climate.America
season = .America
switch season {
   case .India:
      print("Climate is Hot")
   case .America:
      print("Climate is Cold")
   case .Africa:
      print("Climate is Moderate")
   case .Australia:
      print("Climate is Rainy")

}

プレイグラウンドを使用して上記のプログラムを実行すると、次の結果が得られます-

Climate is Cold

プログラムは最初に気候を列挙名として定義します。 その後、「インド」、「アメリカ」、「アフリカ」、「オーストラリア」などのメンバーは、クラス「気候」に属すると宣言されます。 これで、メンバーAmericaがシーズン変数に割り当てられました。 さらに、Switch caseは.Americaに対応する値を確認し、その特定のステートメントに分岐します。 出力は「気候は寒い」と表示されます。 同様に、すべてのメンバーはswitchステートメントを介してアクセスできます。 条件が満たされない場合、デフォルトで「気候は予測不可能です」と印刷されます。

列挙は、関連する値と生の値にさらに分類できます。

関連する値と生の値の違い

Associated Values Raw Values
Different Datatypes Same Datatypes
Ex: enum \{10,0.8,"Hello"} Ex: enum \{10,35,50}
Values are created based on constant or variable Prepopulated Values
Varies when declared each time Value for member is same

関連する値を持つ列挙

enum Student {
   case Name(String)
   case Mark(Int,Int,Int)
}

var studDetails = Student.Name("Swift 4")
var studMarks = Student.Mark(98,97,95)

switch studMarks {
   case .Name(let studName):
      print("Student name is: \(studName).")
   case .Mark(let Mark1, let Mark2, let Mark3):
      print("Student Marks are: \(Mark1),\(Mark2),\(Mark3).")
}

プレイグラウンドを使用して上記のプログラムを実行すると、次の結果が得られます-

Student Marks are: 98,97,95.

たとえば、3つのサブジェクトで保護されている学生の名前とマークにアクセスするとします。列挙名はstudentとして宣言され、enumクラスに存在するメンバーは文字列データ型に属する名前です。 学生の名前または採点したマークにアクセスするには

var studDetails = Student.Name("Swift")
var studMarks = Student.Mark(98,97,95)

現在、switch caseは、そのcaseブロックが実行された場合、学生名を印刷します。そうでない場合、学生によって保護されたマークを印刷します。 両方の条件が満たされない場合、デフォルトのブロックが実行されます。

生の値を持つ列挙

生の値は、文字列、文字、または整数型または浮動小数点型のいずれかです。 各生の値は、列挙宣言内で一意である必要があります。 生の値に整数が使用されている場合、一部の列挙メンバーに値が指定されていない場合、整数は自動的に増加します。

enum Month: Int {
   case January = 1, February, March, April, May, June, July, August,
      September, October, November, December
}

let yearMonth = Month.May.rawValue
print("Value of the Month is: \(yearMonth).")

プレイグラウンドを使用して上記のプログラムを実行すると、次の結果が得られます-

Value of the Month is: 5.

Swift-構造

Swift 4は、構造体を構造体として使用する柔軟なビルディングブロックを提供します。 これらの構造を利用することにより、コンストラクトのメソッドとプロパティを一度定義できます。

CやObjective Cとは異なり

  • 構造は、実装ファイルとインターフェイスを必要としません。
  • 構造により、単一のファイルを作成し、そのインターフェイスを他のブロックに自動的に拡張できます。

構造では、値を変更できないように、古い値のコピーを返すことにより、変数値がコピーされ、後続のコードで渡されます。

構文

Structures are defined with a 'Struct' Keyword.
struct nameStruct {
   Definition 1
   Definition 2
   ---
   Definition N
}

構造の定義

たとえば、3つの科目のマークを含む学生レコードにアクセスし、3つの科目の合計を調べる必要があるとします。 ここでは、markStructを使用して、データ型「Int」として3つのマークを持つ構造を初期化します。

struct MarkStruct {
   var mark1: Int
   var mark2: Int
   var mark3: Int
}

構造とそのプロパティへのアクセス

構造体のメンバーは、その構造体名によってアクセスされます。 構造体のインスタンスは、「let」キーワードによって初期化されます。

struct studentMarks {
   var mark1 = 100
   var mark2 = 200
   var mark3 = 300
}

let marks = studentMarks()
print("Mark1 is \(marks.mark1)")
print("Mark2 is \(marks.mark2)")
print("Mark3 is \(marks.mark3)")

プレイグラウンドを使用して上記のプログラムを実行すると、次の結果が得られます-

Mark1 is 100
Mark2 is 200
Mark3 is 300

学生マークには、構造名「studentMarks」でアクセスします。 構造体のメンバーは、整数型の値でmark1、mark2、mark3として初期化されます。 次に、studentMarks()構造が「let」キーワードとともに「marks」に渡されます。 これ以降、「マーク」には構造体のメンバー値が含まれます。 これで、構造メンバーの値に「。」でアクセスして値が出力されます。初期化された名前。

struct MarksStruct {
   var mark: Int

   init(mark: Int) {
      self.mark = mark
   }
}

var aStruct = MarksStruct(mark: 98)
var bStruct = aStruct    //aStruct and bStruct are two structs with the same value!
bStruct.mark = 97

print(aStruct.mark)     //98
print(bStruct.mark)     //97

プレイグラウンドを使用して上記のプログラムを実行すると、次の結果が得られます-

98
97

構造の最適な使用法

Swift 4言語は、機能ブロックを構築するためのカスタムデータ型として構造を定義する機能を提供します。 構造のインスタンスは、その値によって、さらに操作するために定義されたブロックに渡されます。

構造を持つ必要性

  • 単純なデータ値をカプセル化します。
  • カプセル化されたデータとその関連プロパティを「参照」ではなく「値」でコピーします。
  • 「コピー」および「参照」する構造。

Swift 4の構造体は、参照ではなく、メンバーに値を渡します。

struct markStruct {
   var mark1: Int
   var mark2: Int
   var mark3: Int

   init(mark1: Int, mark2: Int, mark3: Int) {
      self.mark1 = mark1
      self.mark2 = mark2
      self.mark3 = mark3
   }
}

var marks = markStruct(mark1: 98, mark2: 96, mark3:100)
print(marks.mark1)
print(marks.mark2)
print(marks.mark3)

プレイグラウンドを使用して上記のプログラムを実行すると、次の結果が得られます-

98
96
100

もう一つの例

struct markStruct {
   var mark1: Int
   var mark2: Int
   var mark3: Int

   init(mark1: Int, mark2: Int, mark3: Int) {
      self.mark1 = mark1
      self.mark2 = mark2
      self.mark3 = mark3
   }
}

var fail = markStruct(mark1: 34, mark2: 42, mark3: 13)

print(fail.mark1)
print(fail.mark2)
print(fail.mark3)

プレイグラウンドを使用して上記のプログラムを実行すると、次の結果が得られます-

34
42
13

構造 'markStruct’は、メンバーmark1、mark2、およびmark3で最初に定義されます。 メンバークラスの変数は、整数値を保持するように初期化されました。 次に、「self」キーワードを使用して構造メンバーのコピーが作成されます。 構造体メンバーのコピーが作成されると、パラメーターマークを持つ構造体ブロックが「marks」変数に渡され、生徒のマークが保持されます。 その後、マークは98、96、100として印刷されます。 同じ構造体メンバーの次の手順では、「fail」という名前の別のインスタンスを使用して、同じ構造体メンバーに異なるマークを付けます。 次に、結果は34、42、13として印刷されます。 これは、構造体がメンバー変数のコピーを持ち、メンバーを今後の機能ブロックに渡すことを明確に説明しています。

スイフト-クラス

Swift 4のクラスは、柔軟な構造のビルディングブロックです。 定数、変数、関数と同様に、ユーザーはクラスのプロパティとメソッドを定義できます。 Swift 4は、クラスを宣言する際にユーザーがインターフェースや実装ファイルを作成する必要がない機能を提供します。 Swift 4では、クラスを単一のファイルとして作成でき、クラスが初期化されるとデフォルトで外部インターフェースが作成されます。

クラスを持つことの利点

  • 継承は、あるクラスのプロパティを別のクラスに取得します
  • 型キャストにより、ユーザーは実行時にクラス型を確認できます
  • 初期化解除はメモリリソースの解放を処理します
  • 参照カウントにより、クラスインスタンスに複数の参照を持たせることができます

クラスと構造の共通特性

  • プロパティを定義して値を保存します
  • 値へのアクセスを提供するための添え字が定義されています
  • 機能を改善するためにメソッドが初期化されます
  • 初期状態は初期化子によって定義されます
  • 機能はデフォルト値を超えて拡張されています
  • プロトコル機能標準の確認

構文

Class classname {
   Definition 1
   Definition 2
   ---
   Definition N
}

クラス定義

class student {
   var studname: String
   var mark: Int
   var mark2: Int
}

インスタンスを作成するための構文

let studrecord = student()

class MarksStruct {
   var mark: Int
   init(mark: Int) {
      self.mark = mark
   }
}

class studentMarks {
   var mark = 300
}

let marks = studentMarks()
print("Mark is \(marks.mark)")

プレイグラウンドを使用して上記のプログラムを実行すると、次の結果が得られます-

Mark is 300

参照型としてのクラスプロパティへのアクセス

クラスのプロパティには「。」でアクセスできます構文。 プロパティ名は「。」で区切られますインスタンス名の後。

class MarksStruct {
   var mark: Int
   init(mark: Int) {
      self.mark = mark
   }
}

class studentMarks {
   var mark1 = 300
   var mark2 = 400
   var mark3 = 900
}

let marks = studentMarks()
print("Mark1 is \(marks.mark1)")
print("Mark2 is \(marks.mark2)")
print("Mark3 is \(marks.mark3)")

プレイグラウンドを使用して上記のプログラムを実行すると、次の結果が得られます-

Mark1 is 300
Mark2 is 400
Mark3 is 900

クラスID演算子

Swift 4のクラスは、単一のインスタンスを指す複数の定数と変数を参照します。 特定のクラスインスタンスID演算子を指す定数と変数について知るために使用されます。 クラスインスタンスは常に参照渡しされます。 クラスでは、NSString、NSArray、およびNSDictionaryインスタンスは常にコピーとしてではなく、既存のインスタンスへの参照として割り当てられ、渡されます。

Identical to Operators Not Identical to Operators
Operator used is (===) Operator used is (!==)
Returns true when two constants or variables pointing to a same instance Returns true when two constants or variables pointing to a different instance
class SampleClass: Equatable {
   let myProperty: String
   init(s: String) {
      myProperty = s
   }
}

func ==(lhs: SampleClass, rhs: SampleClass) -> Bool {
   return lhs.myProperty == rhs.myProperty
}

let spClass1 = SampleClass(s: "Hello")
let spClass2 = SampleClass(s: "Hello")

spClass1 === spClass2//false
print("\(spClass1)")

spClass1 !== spClass2//true
print("\(spClass2)")

プレイグラウンドを使用して上記のプログラムを実行すると、次の結果が得られます-

main.SampleClass
main.SampleClass

Swift-プロパティ

Swift 4言語は、値を関連付けるクラス、列挙、または構造のプロパティを提供します。 プロパティは、保存プロパティと計算プロパティにさらに分類できます。

格納プロパティと計算プロパティの違い

Stored Property Computed Property
Store constant and variable values as instance Calculate a value rather than storing the value
Provided by classes and structures Provided by classes, enumerations and structures

StoredプロパティとComputedプロパティの両方がインスタンスタイプに関連付けられています。 プロパティがそのタイプ値に関連付けられている場合、「タイププロパティ」として定義されます。 格納および計算されたプロパティは、通常、特定のタイプのインスタンスに関連付けられています。 ただし、プロパティをタイプ自体に関連付けることもできます。 このようなプロパティは、タイププロパティと呼ばれます。 プロパティオブザーバーも使用されます

  • 格納されたプロパティの値を観察するには
  • スーパークラスから派生した継承サブクラスのプロパティを観察するには

保存されたプロパティ

Swift 4では、定数および変数のインスタンスを保存するためのStored Propertyコンセプトが導入されています。 定数の保存プロパティは「let」キーワードによって定義され、変数の保存プロパティは「var」キーワードによって定義されます。

  • 定義中に、保存されたプロパティは「デフォルト値」を提供します
  • 初期化中に、ユーザーは初期値を初期化および変更できます
struct Number {
   var digits: Int
   let pi = 3.1415
}

var n = Number(digits: 12345)
n.digits = 67

print("\(n.digits)")
print("\(n.pi)")

プレイグラウンドを使用して上記のプログラムを実行すると、次の結果が得られます-

67
3.1415

上記のコードの次の行を考慮してください-

let pi = 3.1415

ここで、変数piは、インスタンスpi = 3.1415の保存されたプロパティ値として初期化されます。 したがって、インスタンスが参照されるたびに、値3.1415のみが保持されます。

プロパティを保存する別の方法は、定数構造として使用することです。 したがって、構造体のインスタンス全体が「定数の保存プロパティ」と見なされます。

struct Number {
   var digits: Int
   let numbers = 3.1415
}

var n = Number(digits: 12345)
n.digits = 67

print("\(n.digits)")
print("\(n.numbers)")
n.numbers = 8.7

プレイグラウンドを使用して上記のプログラムを実行すると、次の結果が得られます-

error: cannot assign to 'numbers' in 'n'
n.numbers = 8.7

'number’を8.7に再初期化する代わりに、 'number’が定数として宣言されていることを示すエラーメッセージを返します。

遅延保存プロパティ

Swift 4は、 'Lazy Stored Property’と呼ばれる柔軟なプロパティを提供します。このプロパティでは、変数が初めて初期化されるときに初期値を計算しません。 'lazy’修飾子は、変数宣言の前に使用され、遅延保存プロパティとして使用されます。

遅延プロパティが使用されます-

  • オブジェクトの作成を遅らせるため。
  • プロパティがクラスの他の部分に依存している場合、それらはまだ知られていない
class sample {
   lazy var no = number()   //`var` declaration is required.
}

class number {
   var name = "Swift 4"
}

var firstsample = sample()
print(firstsample.no.name)

プレイグラウンドを使用して上記のプログラムを実行すると、次の結果が得られます-

Swift 4

インスタンス変数

Objective Cでは、保存されたプロパティには、保存されたプロパティで宣言された値を保存するためのバックアップ用のインスタンス変数もあります。

Swift 4は、これらの両方の概念を単一の「格納プロパティ」宣言に統合します。 対応するインスタンス変数とバックアップ値を持つ代わりに、「格納プロパティ」には、変数名、データ型、メモリ管理機能によって変数プロパティに関する単一の場所で定義されたすべての統合情報が含まれます。

計算プロパティ

計算されたプロパティの値を保存するのではなく、他のプロパティと値を間接的に取得および設定するゲッターとオプションのセッターを提供します。

class sample {
   var no1 = 0.0, no2 = 0.0
   var length = 300.0, breadth = 150.0

   var middle: (Double, Double) {
      get {
         return (length/2, breadth/2)
      }

      set(axis){
         no1 = axis.0 - (length/2)
         no2 = axis.1 - (breadth/2)
      }
   }
}

var result = sample()
print(result.middle)
result.middle = (0.0, 10.0)

print(result.no1)
print(result.no2)

プレイグラウンドを使用して上記のプログラムを実行すると、次の結果が得られます-

(150.0, 75.0)
-150.0
-65.0

計算されたプロパティが新しい値を未定義のままにすると、その特定の変数にデフォルト値が設定されます。

読み取り専用プロパティとしての計算プロパティ

計算されたプロパティの読み取り専用プロパティは、ゲッターはあるがセッターはないプロパティとして定義されます。 値を返すために常に使用されます。 変数は、「。」を介してさらにアクセスされます。構文ですが、別の値に設定することはできません。

class film {
   var head = ""
   var duration = 0.0
   var metaInfo: [String:String] {
      return [
         "head": self.head,
         "duration":"\(self.duration)"
      ]
   }
}

var movie = film()
movie.head = "Swift 4 Properties"
movie.duration = 3.09

print(movie.metaInfo["head"]!)
print(movie.metaInfo["duration"]!)

プレイグラウンドを使用して上記のプログラムを実行すると、次の結果が得られます-

Swift 4 Properties
3.09

プロパティオブザーバーとしての計算プロパティ

Swift 4では、プロパティ値を監視して応答するために、プロパティオブザーバーが使用されます。 プロパティ値が設定されるたびに、プロパティオブザーバが呼び出されます。 レイジーストアドプロパティを除き、メソッド 'overriding’によってプロパティオブザーバを 'inherited’プロパティに追加できます。

プロパティオブザーバーは次のいずれかで定義できます

  • 値を保存する前に-willset
  • 新しい値を保存した後-didset
  • プロパティがイニシャライザーに設定されている場合、willsetおよびdidsetオブザーバーを呼び出すことはできません。
class Samplepgm {
   var counter: Int = 0 {
      willSet(newTotal){
         print("Total Counter is: \(newTotal)")
      }

      didSet {
         if counter > oldValue {
            print("Newly Added Counter \(counter - oldValue)")
         }
      }
   }
}

let NewCounter = Samplepgm()
NewCounter.counter = 100
NewCounter.counter = 800

プレイグラウンドを使用して上記のプログラムを実行すると、次の結果が得られます-

Total Counter is: 100
Newly Added Counter 100
Total Counter is: 800
Newly Added Counter 700

ローカル変数とグローバル変数

ローカル変数とグローバル変数は、プロパティの計算と監視のために宣言されます。

Local Variables Global Variables
Variables that are defined within a function, method, or closure context. Variables that are defined outside function, method, closure, or type context.
Used to store and retrieve values. Used to store and retrieve values.
Stored properties is used to get and set the values. Stored properties is used to get and set the values.
Computed properties are also used. Computed properties are also used.

タイプのプロパティ

プロパティは、タイプ定義セクションで中括弧\ {}で定義され、変数のスコープも以前に定義されています。 値型の型プロパティを定義するには「静的」キーワードが使用され、クラス型には「クラス」キーワードが使用されます。

構文

struct Structname {
   static var storedTypeProperty = " "
   static var computedTypeProperty: Int {
     //return an Int value here
   }
}

enum Enumname {
   static var storedTypeProperty = " "
   static var computedTypeProperty: Int {
     //return an Int value here
   }
}

class Classname {
   class var computedTypeProperty: Int {
     //return an Int value here
   }
}

プロパティのクエリと設定

インスタンスプロパティのように、タイププロパティがクエリされ、「。」で設定されます。インスタンスを指すのではなく、タイプのみの構文。

struct StudMarks {
   static let markCount = 97
   static var totalCount = 0

   var InternalMarks: Int = 0 {
      didSet {
         if InternalMarks > StudMarks.markCount {
            InternalMarks = StudMarks.markCount
         }
         if InternalMarks > StudMarks.totalCount {
            StudMarks.totalCount = InternalMarks
         }
      }
   }
}

var stud1Mark1 = StudMarks()
var stud1Mark2 = StudMarks()

stud1Mark1.InternalMarks = 98
print(stud1Mark1.InternalMarks)

stud1Mark2.InternalMarks = 87
print(stud1Mark2.InternalMarks)

プレイグラウンドを使用して上記のプログラムを実行すると、次の結果が得られます-

97
87

Swift-メソッド

Swift 4言語では、特定のタイプに関連付けられた関数はメソッドと呼ばれます。 Objective Cでは、クラスを使用してメソッドを定義しますが、Swift 4言語では、クラス、構造体、および列挙のメソッドを柔軟に使用できます。

インスタンスメソッド

Swift 4言語では、クラス、構造、および列挙インスタンスはインスタンスメソッドを介してアクセスされます。

インスタンスメソッドは機能を提供します

  • インスタンスのプロパティにアクセスして変更するには
  • インスタンスのニーズに関連する機能

インスタンスメソッドは、\ {}中括弧内に記述できます。 型インスタンスのメソッドおよびプロパティに暗黙的にアクセスできます。 型の特定のインスタンスが呼び出されると、その特定のインスタンスにアクセスします。

構文

func funcname(Parameters) -> returntype {
   Statement1
   Statement2
   ---
   Statement N
   return parameters
}

class calculations {
   let a: Int
   let b: Int
   let res: Int

   init(a: Int, b: Int) {
      self.a = a
      self.b = b
      res = a + b
   }

   func tot(c: Int) -> Int {
      return res - c
   }

   func result() {
      print("Result is: \(tot(c: 20))")
      print("Result is: \(tot(c: 50))")
   }
}
let pri = calculations(a: 600, b: 300)
pri.result()

プレイグラウンドを使用して上記のプログラムを実行すると、次の結果が得られます-

Result is: 880
Result is: 850

クラスの計算は、2つのインスタンスメソッドを定義します-

  • init()は、2つの数値aとbを追加し、結果「res」に格納するように定義されています *tot()は、「c」値を渡すことから「res」を減算するために使用されます

最後に、aとbの値を持つ計算メソッドを印刷するために呼び出されます。 インスタンスメソッドには「。」でアクセスしますドット構文

ローカルおよび外部パラメーター名

Swift 4関数は、変数のローカル宣言とグローバル宣言の両方を記述します。 同様に、Swift 4メソッドの命名規則もObjective Cのそれに似ています。 ただし、ローカルとグローバルのパラメーター名宣言の特性は、関数とメソッドで異なります。 Swift 4の最初のパラメーターは、アクセスしやすい命名規則のために、「with」、「for」、および「by」として前置詞名で参照されます。

Swift 4は、最初のパラメーター名をローカルパラメーター名として宣言し、残りのパラメーター名をグローバルパラメーター名として宣言することにより、メソッドに柔軟性を提供します。 ここで、「no1」はSwift 4のメソッドによってローカルパラメーター名として宣言されています。 「no2」はグローバル宣言に使用され、プログラム全体でアクセスされます。

class division {
   var count: Int = 0
   func incrementBy(no1: Int, no2: Int) {
      count = no1/no2
      print(count)
   }
}

let counter = division()
counter.incrementBy(no1: 1800, no2: 3)
counter.incrementBy(no1: 1600, no2: 5)
counter.incrementBy(no1: 11000, no2: 3)

プレイグラウンドを使用して上記のプログラムを実行すると、次の結果が得られます-

600
320
3666

#および_記号付きの外部パラメーター名

Swift 4のメソッドはローカル宣言の最初のパラメーター名を提供しますが、ユーザーはパラメーター名をローカル宣言からグローバル宣言に変更することができます。 これは、「#」記号の先頭に最初のパラメーター名を付けることで実行できます。 そうすることで、モジュール全体で最初のパラメーターにグローバルにアクセスできます。

ユーザーが外部名を使用して後続のパラメーター名にアクセスする必要がある場合、メソッド名は「_」記号を使用してオーバーライドされます。

class multiplication {
   var count: Int = 0
   func incrementBy(no1: Int, no2: Int) {
      count = no1* no2
      print(count)
   }
}

let counter = multiplication()

counter.incrementBy(no1: 800, no2: 3)
counter.incrementBy(no1: 100, no2: 5)
counter.incrementBy(no1: 15000, no2: 3)

プレイグラウンドを使用して上記のプログラムを実行すると、次の結果が得られます-

2400
500
45000

メソッドの自己プロパティ

メソッドには、定義されたすべての型インスタンスに対して「自己」と呼ばれる暗黙のプロパティがあります。 'Self’プロパティは、定義されたメソッドの現在のインスタンスを参照するために使用されます。

class calculations {
   let a: Int
   let b: Int
   let res: Int

   init(a: Int, b: Int) {
      self.a = a
      self.b = b
      res = a + b
      print("Inside Self Block: \(res)")
   }

   func tot(c: Int) -> Int {
      return res - c
   }

   func result() {
      print("Result is: \(tot(c: 20))")
      print("Result is: \(tot(c: 50))")
   }
}

let pri = calculations(a: 600, b: 300)
let sum = calculations(a: 1200, b: 300)

pri.result()
sum.result()

プレイグラウンドを使用して上記のプログラムを実行すると、次の結果が得られます-

Inside Self Block: 900
Inside Self Block: 1500
Result is: 880
Result is: 850
Result is: 1480
Result is: 1450

インスタンスメソッドからの値タイプの変更

Swift 4では、言語構造と列挙は、そのインスタンスメソッドで変更できない値型に属します。 ただし、Swift 4言語では、動作を「変更」することで値の型を柔軟に変更できます。 Mutateは、インスタンスメソッドに変更を加え、メソッドの実行後に元のフォームに戻ります。 また、「self」プロパティによって、暗黙的な機能のために新しいインスタンスが作成され、実行後に既存のメソッドを置き換えます

struct area {
   var length = 1
   var breadth = 1

   func area() -> Int {
      return length *breadth
   }
   mutating func scaleBy(res: Int) {
      length* = res
      breadth *= res
      print(length)
      print(breadth)
   }
}

var val = area(length: 3, breadth: 5)
val.scaleBy(res: 3)
val.scaleBy(res: 30)
val.scaleBy(res: 300)

プレイグラウンドを使用して上記のプログラムを実行すると、次の結果が得られます-

9
15
270
450
81000
135000

変異法の自己特性

「self」プロパティと組み合わせたメソッドを変更すると、新しいインスタンスが定義済みのメソッドに割り当てられます。

struct area {
   var length = 1
   var breadth = 1
   func area() -> Int {
      return length *breadth
   }
   mutating func scaleBy(res: Int) {
      self.length* = res
      self.breadth *= res
      print(length)
      print(breadth)
   }
}

var val = area(length: 3, breadth: 5)
val.scaleBy(res: 13)

プレイグラウンドを使用して上記のプログラムを実行すると、次の結果が得られます。 −

39
65

型メソッド

メソッドの特定のインスタンスが呼び出されると、インスタンスメソッドとして呼び出されます。また、メソッドが特定のタイプのメソッドを呼び出す場合、「タイプメソッド」と呼ばれます。 「クラス」の型メソッドは「func」キーワードで定義され、構造体と列挙型のメソッドは「func」キーワードの前の「static」キーワードで定義されます。

型メソッドは「。」によって呼び出され、アクセスされます特定のインスタンスを呼び出す代わりに、メソッド全体が呼び出される構文。

class Math {
   class func abs(number: Int) -> Int {
      if number < 0 {
         return (-number)
      } else {
         return number
      }
   }
}

struct absno {
   static func abs(number: Int) -> Int {
      if number < 0 {
         return (-number)
      } else {
         return number
      }
   }
}

let no = Math.abs(number: -35)
let num = absno.abs(number: -5)

print(no)
print(num)

プレイグラウンドを使用して上記のプログラムを実行すると、次の結果が得られます。 −

35
5

Swift-添え字

クラス、構造、および列挙のコレクション、シーケンス、およびリストの要素メンバーへのアクセスは、添え字を使用して実行されます。 これらの添え字は、インデックスを使用して値を保存および取得するために使用されます。 配列要素はsomeArray [index]の助けを借りてアクセスされ、Dictionaryインスタンスの後続のメンバー要素はsomeDicitonary [key]としてアクセスできます。

単一の型の場合、添字の範囲は単一から複数の宣言までです。 適切な添え字を使用して、添え字に渡されるインデックス値のタイプをオーバーロードできます。 下付き文字は、入力データ型宣言のユーザー要件に応じて、単一ディメンションから複数ディメンションまでの範囲もあります。

下付き宣言の構文とその使用法

計算されたプロパティの要約をしましょう。 下付き文字も、計算されたプロパティと同じ構文に従います。 タイプのインスタンスを照会する場合、サブスクリプトは角括弧内に書き込まれ、その後にインスタンス名が続きます。 添え字構文は、「インスタンスメソッド」および「計算プロパティ」構文と同じ構文構造に従います。 「添字」キーワードは添字の定義に使用され、ユーザーは単一または複数のパラメーターを戻り値の型で指定できます。 添字には読み取り/書き込みまたは読み取り専用のプロパティを設定でき、インスタンスは計算プロパティの「getter」および「setter」プロパティを使用して保存および取得できます。

構文

subscript(index: Int) −> Int {
   get {
     //used for subscript value declarations
   }
   set(newValue) {
     //definitions are written here
   }
}

例1

struct subexample {
   let decrementer: Int
   subscript(index: Int) -> Int {
      return decrementer/index
   }
}
let division = subexample(decrementer: 100)

print("The number is divisible by \(division[9]) times")
print("The number is divisible by \(division[2]) times")
print("The number is divisible by \(division[3]) times")
print("The number is divisible by \(division[5]) times")
print("The number is divisible by \(division[7]) times")

プレイグラウンドを使用して上記のプログラムを実行すると、次の結果が得られます-

The number is divisible by 11 times
The number is divisible by 50 times
The number is divisible by 33 times
The number is divisible by 20 times
The number is divisible by 14 times

例2

class daysofaweek {
   private var days = ["Sunday", "Monday", "Tuesday", "Wednesday",
      "Thursday", "Friday", "saturday"]
   subscript(index: Int) -> String {
      get {
         return days[index]
      }
      set(newValue) {
         self.days[index] = newValue
      }
   }
}
var p = daysofaweek()

print(p[0])
print(p[1])
print(p[2])
print(p[3])

プレイグラウンドを使用して上記のプログラムを実行すると、次の結果が得られます-

Sunday
Monday
Tuesday
Wednesday

下付き文字のオプション

添え字は単一から複数の入力パラメーターを取り、これらの入力パラメーターも任意のデータ型に属します。 また、変数および可変パラメータを使用できます。 添え字は、デフォルトのパラメーター値を提供したり、入出力パラメーターを使用したりすることはできません。

複数の添え字の定義は、「添え字のオーバーロード」と呼ばれ、クラスまたは構造は必要に応じて複数の添え字定義を提供できます。 これらの複数の添え字は、添え字ブレース内で宣言された値のタイプに基づいて推測されます。

struct Matrix {
   let rows: Int, columns: Int
   var print: [Double]
   init(rows: Int, columns: Int) {
      self.rows = rows
      self.columns = columns
      print = Array(count: rows *columns, repeatedValue: 0.0)
   }
   subscript(row: Int, column: Int) -> Double {
      get {
         return print[(row* columns) + column]
      }
      set {
         print[(row *columns) + column] = newValue
      }
   }
}
var mat = Matrix(rows: 3, columns: 3)

mat[0,0] = 1.0
mat[0,1] = 2.0
mat[1,0] = 3.0
mat[1,1] = 5.0

print("\(mat[0,0])")

プレイグラウンドを使用して上記のプログラムを実行すると、次の結果が得られます-

1.0

Swift 4の添字は、適切なデータ型の単一のパラメーターから複数のパラメーター宣言をサポートします。 プログラムは、「Double」データ型を格納するために、「Matrix」構造を2* 2次元配列行列として宣言します。 Matrixパラメーターには、行と列を宣言するための整数データ型が入力されます。

Matrixの新しいインスタンスは、以下に示すように、行と列のカウントを初期化に渡すことで作成されます。

var mat = Matrix(rows: 3, columns: 3)

行列値は、下に示すように、行と列の値を下付き文字にコンマで区切って渡すことで定義できます。

mat[0,0] = 1.0
mat[0,1] = 2.0
mat[1,0] = 3.0
mat[1,1] = 5.0

スイフト-継承

より多くの形式を取る能力は、継承として定義されます。 通常、クラスは別のクラスからメソッド、プロパティ、機能を継承できます。 クラスはさらにサブクラスとスーパークラスに分類できます。

  • サブクラス-クラスが別のクラスからプロパティ、メソッド、および関数を継承する場合、サブクラスとして呼び出されます
  • スーパークラス-他のクラスをそれ自体から継承するためのプロパティ、メソッド、および関数を含むクラスは、スーパークラスと呼ばれます

Swift 4クラスには、メソッド、プロパティ、関数、およびオーバーライドメソッドを呼び出してアクセスするスーパークラスが含まれています。 また、プロパティオブザーバーは、プロパティを追加し、保存または計算されたプロパティメソッドを変更するためにも使用されます。

基本クラス

別のクラスからメソッド、プロパティ、または関数を継承しないクラスは、「基本クラス」と呼ばれます。

class StudDetails {
   var stname: String!
   var mark1: Int!
   var mark2: Int!
   var mark3: Int!

   init(stname: String, mark1: Int, mark2: Int, mark3: Int) {
      self.stname = stname
      self.mark1 = mark1
      self.mark2 = mark2
      self.mark3 = mark3
   }
}

let stname = "Swift 4"
let mark1 = 98
let mark2 = 89
let mark3 = 76

print(stname)
print(mark1)
print(mark2)
print(mark3)

プレイグラウンドを使用して上記のプログラムを実行すると、次の結果が得られます-

Swift 4
98
89
76

クラス名StudDetailsのクラスは、ここでは学生の名前を含むために使用される基本クラスとして定義され、3つの科目はmark1、mark2、mark3としてマークされます。 「let」キーワードは、基本クラスの値を初期化するために使用され、基本クラス値は「print」機能の助けを借りてプレイグラウンドに表示されます。

サブクラス

既存のクラスに基づいて新しいクラスを作成する行為は、「サブクラス」として定義されます。 サブクラスは、基本クラスのプロパティ、メソッド、および機能を継承します。 サブクラスを定義するには、基本クラス名の前に「:」を使用します

class StudDetails {
   var mark1: Int;
   var mark2: Int;

   init(stm1:Int, results stm2:Int) {
      mark1 = stm1;
      mark2 = stm2;
   }
   func print() {
      print("Mark1:\(mark1), Mark2:\(mark2)")
   }
}

class display : StudDetails {
   init() {
      super.init(stm1: 93, results: 89)
   }
}

let marksobtained = display()
marksobtained.print()

プレイグラウンドを使用して上記のプログラムを実行すると、次の結果が得られます-

Mark1:93, Mark2:89

クラス 'StudDetails’は、学生マークが宣言されているスーパークラスとして定義され、サブクラス 'display’は、スーパークラスからマークを継承するために使用されます。 サブクラスは生徒のマークを定義し、print()メソッドを呼び出して生徒のマークを表示します。

オーバーライド

スーパークラスインスタンス、型メソッド、インスタンス、型プロパティ、および添え字サブクラスにアクセスすると、オーバーライドの概念が提供されます。 「override」キーワードは、スーパークラスで宣言されたメソッドをオーバーライドするために使用されます。

スーパークラスのメソッド、プロパティ、サブスクリプトへのアクセス

「スーパー」キーワードは、スーパークラスで宣言されたメソッド、プロパティ、およびサブスクリプトにアクセスするためのプレフィックスとして使用されます

Overriding Access to methods,properties and subscripts
Methods super.somemethod()
Properties super.someProperty()
Subscripts super[someIndex]

メソッドのオーバーライド

継承されたインスタンスおよびタイプのメソッドは、サブクラスで定義されたメソッドの 'override’キーワードによってオーバーライドできます。 ここでは、サブクラスでprint()がオーバーライドされ、スーパークラスのprint()で言及されているtypeプロパティにアクセスします。 また、cricket()スーパークラスの新しいインスタンスが「cricinstance」として作成されます。

class cricket {
   func print() {
      print("Welcome to Swift 4 Super Class")
   }
}

class tennis: cricket {
   override func print() {
      print("Welcome to Swift 4 Sub Class")
   }
}

let cricinstance = cricket()
cricinstance.print()

let tennisinstance = tennis()
tennisinstance.print()

プレイグラウンドを使用して上記のプログラムを実行すると、次の結果が得られます-

Welcome to Swift Super Class
Welcome to Swift Sub Class

プロパティのオーバーライド

継承されたインスタンスまたはクラスプロパティをオーバーライドして、そのプロパティに独自のカスタムgetterおよびsetterを提供したり、プロパティオブザーバを追加して、基になるプロパティ値が変更されたときにオーバーライドプロパティが監視できるようにすることができます。

プロパティゲッターとセッターのオーバーライド

Swift 4では、ユーザーがカスタムgetterおよびsetterを提供して、継承されたプロパティが保存されたプロパティまたは計算されたプロパティであるかどうかをオーバーライドできます。 サブクラスは、継承されたプロパティの名前とタイプを知りません。 したがって、ユーザーがサブクラスで、スーパークラスで指定されたオーバーライドプロパティの名前とタイプを指定する必要があります。

これは2つの方法で行うことができます-

  • プロパティをオーバーライドするためにセッターが定義されている場合、ユーザーはゲッターも定義する必要があります。
  • 継承されたプロパティゲッターを変更したくない場合は、継承された値を構文 'super.someProperty’でスーパークラスに渡すだけです。
class Circle {
   var radius = 12.5
   var area: String {
      return "of rectangle for \(radius) "
   }
}

class Rectangle: Circle {
   var print = 7
   override var area: String {
      return super.area + " is now overridden as \(print)"
   }
}

let rect = Rectangle()
rect.radius = 25.0
rect.print = 3
print("Radius \(rect.area)")

プレイグラウンドを使用して上記のプログラムを実行すると、次の結果が得られます-

Radius of rectangle for 25.0  is now overridden as 3

プロパティオブザーバーのオーバーライド

継承されたプロパティに新しいプロパティを追加する必要がある場合、「プロパティオーバーライド」の概念がSwift 4で導入されます。 これは、継承されたプロパティ値が変更されたときにユーザーに通知します。 ただし、継承された定数保存プロパティおよび継承された読み取り専用の計算プロパティにはオーバーライドは適用されません。

class Circle {
   var radius = 12.5
   var area: String {
     return "of rectangle for \(radius) "
   }
}

class Rectangle: Circle {
   var print = 7
   override var area: String {
      return super.area + " is now overridden as \(print)"
   }
}

let rect = Rectangle()
rect.radius = 25.0
rect.print = 3
print("Radius \(rect.area)")

class Square: Rectangle {
   override var radius: Double {
      didSet {
         print = Int(radius/5.0)+1
      }
   }
}

let sq = Square()
sq.radius = 100.0
print("Radius \(sq.area)")

プレイグラウンドを使用して上記のプログラムを実行すると、次の結果が得られます-

Radius of rectangle for 25.0  is now overridden as 3
Radius of rectangle for 100.0  is now overridden as 21

オーバーライドを防止する最終プロパティ

ユーザーが他の人にスーパークラスのメソッド、プロパティ、または添え字へのアクセスを望まない場合、Swift 4はオーバーライドを防ぐために「最終」プロパティを導入します。 「最終」プロパティが宣言されると、サブスクリプトはスーパークラスのメソッド、プロパティ、およびそのサブスクリプトをオーバーライドできなくなります。 「スーパークラス」に「最終」プロパティを設定する規定はありません。 「最終」プロパティが宣言されると、ユーザーはさらにサブクラスを作成するように制限されます。

final class Circle {
   final var radius = 12.5
   var area: String {
      return "of rectangle for \(radius) "
   }
}

class Rectangle: Circle {
   var print = 7
   override var area: String {
      return super.area + " is now overridden as \(print)"
   }
}

let rect = Rectangle()
rect.radius = 25.0
rect.print = 3
print("Radius \(rect.area)")

class Square: Rectangle {
   override var radius: Double {
      didSet {
         print = Int(radius/5.0)+1
      }
   }
}

let sq = Square()
sq.radius = 100.0
print("Radius \(sq.area)")

プレイグラウンドを使用して上記のプログラムを実行すると、次の結果が得られます-

<stdin>:14:18: error: var overrides a 'final' var
override var area: String {
^
<stdin>:7:9: note: overridden declaration is here
var area: String {
^
<stdin>:12:11: error: inheritance from a final class 'Circle'
class Rectangle: Circle {
^
<stdin>:25:14: error: var overrides a 'final' var
override var radius: Double {
^
<stdin>:6:14: note: overridden declaration is here
final var radius = 12.5

スーパークラスは「final」として宣言され、そのデータ型も「final」として宣言されているため、プログラムはサブクラスをさらに作成できず、エラーがスローされます。

Swift-初期化

Swift 4で宣言されたクラス、構造、および列挙は、クラスのインスタンスを準備するために初期化されます。 格納されたプロパティの初期値が初期化され、新しいインスタンスの初期値も初期化され、さらに先に進みます。 初期化関数を作成するためのキーワードは、「init()」メソッドによって実行されます。 Swift 4初期化子は、値を返さないという点でObjective-Cと異なります。 その機能は、処理前に新しく作成されたインスタンスの初期化をチェックすることです。 Swift 4は、インスタンスの割り当てが解除されると、メモリ管理操作を実行するための「初期化解除」プロセスも提供します。

格納されたプロパティの初期化ロール

格納されたプロパティは、インスタンスを処理する前に、クラスと構造のインスタンスを初期化する必要があります。 格納されたプロパティは、イニシャライザを使用して値を割り当てて初期化し、プロパティオブザーバを呼び出す必要をなくします。 保存されたプロパティで初期化子が使用されます

  • 初期値を作成します。
  • プロパティ定義内でデフォルトのプロパティ値を割り当てます。
  • 特定のデータ型のインスタンスを初期化するには、「init()」を使用します。 init()関数内では引数は渡されません。

構文

init() {
  //New Instance initialization goes here
}

struct rectangle {
   var length: Double
   var breadth: Double
   init() {
      length = 6
      breadth = 12
   }
}

var area = rectangle()
print("area of rectangle is \(area.length*area.breadth)")

プレイグラウンドを使用して上記のプログラムを実行すると、次の結果が得られます-

area of rectangle is 72.0

ここで、構造 'rectangle’は、メンバーの長さと幅を 'Double’データ型として初期化されます。 Init()メソッドは、新しく作成されたメンバーlengthおよびdoubleの値を初期化するために使用されます。 四角形の面積は、四角形関数を呼び出して計算され、返されます。

デフォルトでプロパティ値を設定する

Swift 4言語は、格納されているプロパティ値を初期化するInit()関数を提供します。 また、ユーザーは、クラスまたは構造体のメンバーを宣言するときに、デフォルトでプロパティ値を初期化するためのプロビジョニングを持っています。 プロパティがプログラム全体で同じ値のみをとる場合、init()で初期化するのではなく、宣言セクションで単独で宣言できます。 デフォルトでプロパティ値を設定すると、クラスまたは構造に継承が定義されているときにユーザーが有効になります。

struct rectangle {
   var length = 6
   var breadth = 12
}

var area = rectangle()
print("area of rectangle is \(area.length*area.breadth)")

プレイグラウンドを使用して上記のプログラムを実行すると、次の結果が得られます-

area of rectangle is 72

ここで、init()で長さと幅を宣言する代わりに、値は宣言自体で初期化されます。

パラメータの初期化

Swift 4言語では、ユーザーは、init()を使用して初期化子の定義の一部としてパラメーターを初期化することができます。

struct Rectangle {
   var length: Double
   var breadth: Double
   var area: Double

   init(fromLength length: Double, fromBreadth breadth: Double) {
      self.length = length
      self.breadth = breadth
      area = length *breadth
   }
   init(fromLeng leng: Double, fromBread bread: Double) {
      self.length = leng
      self.breadth = bread
      area = leng* bread
   }
}

let ar = Rectangle(fromLength: 6, fromBreadth: 12)
print("area is: \(ar.area)")

let are = Rectangle(fromLeng: 36, fromBread: 12)
print("area is: \(are.area)")

プレイグラウンドを使用して上記のプログラムを実行すると、次の結果が得られます-

area is: 72.0
area is: 432.0

ローカルおよび外部パラメーター

初期化パラメーターには、関数およびメソッドのパラメーターと同様のローカルおよびグローバルのパラメーター名があります。 ローカルパラメータ宣言は初期化本体内のアクセスに使用され、外部パラメータ宣言は初期化子の呼び出しに使用されます。 Swift 4初期化子は、どの関数を呼び出すためにどの初期化子が使用されるかを識別しないという点で、関数およびメソッドの初期化子と異なります。

これを克服するために、Swift 4はinit()の各パラメーターに自動外部名を導入します。 この自動外部名は、すべての初期化パラメーターの前に記述されたローカル名と同等です。

struct Days {
   let sunday, monday, tuesday: Int
   init(sunday: Int, monday: Int, tuesday: Int) {
      self.sunday = sunday
      self.monday = monday
      self.tuesday = tuesday
   }
   init(daysofaweek: Int) {
      sunday = daysofaweek
      monday = daysofaweek
      tuesday = daysofaweek
   }
}

let week = Days(sunday: 1, monday: 2, tuesday: 3)
print("Days of a Week is: \(week.sunday)")
print("Days of a Week is: \(week.monday)")
print("Days of a Week is: \(week.tuesday)")

let weekdays = Days(daysofaweek: 4)
print("Days of a Week is: \(weekdays.sunday)")
print("Days of a Week is: \(weekdays.monday)")
print("Days of a Week is: \(weekdays.tuesday)")

プレイグラウンドを使用して上記のプログラムを実行すると、次の結果が得られます-

Days of a Week is: 1
Days of a Week is: 2
Days of a Week is: 3
Days of a Week is: 4
Days of a Week is: 4
Days of a Week is: 4

外部名のないパラメーター

アンダースコアの初期化に外部名が必要ない場合、デフォルトの動作をオーバーライドするために「_」が使用されます。

struct Rectangle {
   var length: Double

   init(frombreadth breadth: Double) {
      length = breadth *10
   }
   init(frombre bre: Double) {
      length = bre* 30
   }
   init(_ area: Double) {
      length = area
   }
}

let rectarea = Rectangle(180.0)
print("area is: \(rectarea.length)")

let rearea = Rectangle(370.0)
print("area is: \(rearea.length)")

let recarea = Rectangle(110.0)
print("area is: \(recarea.length)")

プレイグラウンドを使用して上記のプログラムを実行すると、次の結果が得られます-

area is: 180.0
area is: 370.0
area is: 110.0

オプションのプロパティタイプ

あるインスタンスの保存されたプロパティが値を返さない場合、そのプロパティは「オプション」タイプで宣言され、その特定のタイプに対して「値なし」が返されることを示します。 保存されたプロパティが「オプション」として宣言されると、初期化中に値が自動的に「nil」に初期化されます。

struct Rectangle {
   var length: Double?

   init(frombreadth breadth: Double) {
      length = breadth *10
   }
   init(frombre bre: Double) {
      length = bre* 30
   }
   init(_ area: Double) {
      length = area
   }
}

let rectarea = Rectangle(180.0)
print("area is: \(rectarea.length)")

let rearea = Rectangle(370.0)
print("area is: \(rearea.length)")

let recarea = Rectangle(110.0)
print("area is: \(recarea.length)")

プレイグラウンドを使用して上記のプログラムを実行すると、次の結果が得られます-

area is: Optional(180.0)
area is: Optional(370.0)
area is: Optional(110.0)

初期化中の定数プロパティの変更

また、初期化により、ユーザーは定数プロパティの値も変更できます。 初期化中に、クラスプロパティを使用すると、サブクラスではなくスーパークラスによってクラスインスタンスを変更できます。 たとえば、前のプログラムで、「長さ」がメインクラスで「変数」として宣言されていることを考慮してください。 以下のプログラム変数「長さ」は「定数」変数として変更されます。

struct Rectangle {
   let length: Double?

   init(frombreadth breadth: Double) {
      length = breadth *10
   }
   init(frombre bre: Double) {
      length = bre* 30
   }
   init(_ area: Double) {
      length = area
   }
}

let rectarea = Rectangle(180.0)
print("area is: \(rectarea.length)")

let rearea = Rectangle(370.0)
print("area is: \(rearea.length)")

let recarea = Rectangle(110.0)
print("area is: \(recarea.length)")

プレイグラウンドを使用して上記のプログラムを実行すると、次の結果が得られます-

area is: Optional(180.0)
area is: Optional(370.0)
area is: Optional(110.0)

デフォルトの初期化子

デフォルトの初期化子は、デフォルト値を持つ基本クラスまたは構造体のすべての宣言されたプロパティに新しいインスタンスを提供します。

class defaultexample {
   var studname: String?
   var stmark = 98
   var pass = true
}
var result = defaultexample()

print("result is: \(result.studname)")
print("result is: \(result.stmark)")
print("result is: \(result.pass)")

プレイグラウンドを使用して上記のプログラムを実行すると、次の結果が得られます。 −

result is: nil
result is: 98
result is: true

上記のプログラムは、クラス名を「defaultexample」として定義されています。 3つのメンバー関数は、デフォルトで「studname?」として初期化されます「nil」値、「stmark」を98、「pass」をブール値「true」として保存します。 同様に、クラスのメンバータイプを処理する前に、クラスのメンバー値をデフォルトとして初期化できます。

構造型のメンバーごとの初期化子

カスタム初期化子がユーザーによって提供されない場合、Swift 4の構造型は自動的に「メンバーごとの初期化子」を受け取ります。 その主な機能は、デフォルトのメンバーごとの初期化で新しい構造体インスタンスを初期化することです。その後、新しいインスタンスプロパティが名前ごとにメンバーごとに初期化されます。

struct Rectangle {
   var length = 100.0, breadth = 200.0
}
let area = Rectangle(length: 24.0, breadth: 32.0)

print("Area of rectangle is: \(area.length)")
print("Area of rectangle is: \(area.breadth)")

プレイグラウンドを使用して上記のプログラムを実行すると、次の結果が得られます-

Area of rectangle is: 24.0
Area of rectangle is: 32.0

構造体は、「長さ」を「100.0」、「幅」を「200.0」として初期化するときに、メンバーシップ関数に対してデフォルトで初期化されます。 ただし、変数の長さおよび幅の処理中、値は24.0および32.0としてオーバーライドされます。

値型の初期化子委任

初期化子委任は、他の初期化子から初期化子を呼び出すこととして定義されます。 その主な機能は、複数の初期化子間でのコードの重複を回避するための再利用性として機能することです。

struct Stmark {
   var mark1 = 0.0, mark2 = 0.0
}
struct stdb {
   var m1 = 0.0, m2 = 0.0
}

struct block {
   var average = stdb()
   var result = Stmark()
   init() {}
   init(average: stdb, result: Stmark) {
      self.average = average
      self.result = result
   }

   init(avg: stdb, result: Stmark) {
      let tot = avg.m1 - (result.mark1/2)
      let tot1 = avg.m2 - (result.mark2/2)
      self.init(average: stdb(m1: tot, m2: tot1), result: result)
   }
}

let set1 = block()
print("student result is: \(set1.average.m1, set1.average.m2)
\(set1.result.mark1, set1.result.mark2)")

let set2 = block(average: stdb(m1: 2.0, m2: 2.0),
result: Stmark(mark1: 5.0, mark2: 5.0))
print("student result is: \(set2.average.m1, set2.average.m2)
\(set2.result.mark1, set2.result.mark2)")

let set3 = block(avg: stdb(m1: 4.0, m2: 4.0),
result: Stmark(mark1: 3.0, mark2: 3.0))
print("student result is: \(set3.average.m1, set3.average.m2)
\(set3.result.mark1, set3.result.mark2)")

プレイグラウンドを使用して上記のプログラムを実行すると、次の結果が得られます-

(0.0,0.0) (0.0,0.0)
(2.0,2.0) 5.0,5.0)
(2.5,2.5) (3.0,3.0)

初期化子委任のルール

Value Types Class Types
Inheritance is not supported for value types like structures and enumerations. Referring other initializers is done through self.init Inheritance is supported. Checks all stored property values are initialized

クラスの継承と初期化

クラス型には、定義された保存済みプロパティが初期値、つまり指定された初期化子と便利な初期化子を受け取るかどうかを確認するための2種類の初期化子があります。

指定された初期化子と便利な初期化子

Designated Initializer Convenience Initializer
Considered as primary initializes for a class Considered as supporting initialize for a class
All class properties are initialized and appropriate superclass initializer are called for further initialization Designated initializer is called with convenience initializer to create class instance for a specific use case or input value type
At least one designated initializer is defined for every class No need to have convenience initializers compulsory defined when the class does not require initializers.
Init(parameters) \{ statements } convenience init(parameters) \{ statements }

指定された初期化プログラム

class mainClass {
   var no1 : Int//local storage
   init(no1 : Int) {
      self.no1 = no1//initialization
   }
}

class subClass : mainClass {
   var no2 : Int//new subclass storage
   init(no1 : Int, no2 : Int) {
      self.no2 = no2//initialization
      super.init(no1:no1)//redirect to superclass
   }
}

let res = mainClass(no1: 10)
let print = subClass(no1: 10, no2: 20)

print("res is: \(res.no1)")
print("res is: \(print.no1)")
print("res is: \(print.no2)")

プレイグラウンドを使用して上記のプログラムを実行すると、次の結果が得られます-

res is: 10
res is: 10
res is: 20

便利な初期化プログラム

class mainClass {
   var no1 : Int//local storage
   init(no1 : Int) {
      self.no1 = no1//initialization
   }
}

class subClass : mainClass {
   var no2 : Int
   init(no1 : Int, no2 : Int) {
      self.no2 = no2
      super.init(no1:no1)
   }
  //Requires only one parameter for convenient method
   override convenience init(no1: Int) {
      self.init(no1:no1, no2:0)
   }
}

let res = mainClass(no1: 20)
let print = subClass(no1: 30, no2: 50)

print("res is: \(res.no1)")
print("res is: \(print.no1)")
print("res is: \(print.no2)")

プレイグラウンドを使用して上記のプログラムを実行すると、次の結果が得られます-

res is: 20
res is: 30
res is: 50

初期化子の継承とオーバーライド

Swift 4では、デフォルトでは、サブクラスがそのメンバータイプのスーパークラス初期化子を継承することを許可していません。 継承は、自動イニシャライザの継承で説明するある程度まで、スーパークラスのイニシャライザにのみ適用できます。

ユーザーがスーパークラスで初期化子を定義する必要がある場合、初期化子を持つサブクラスをカスタム実装としてユーザーが定義する必要があります。 サブクラスによってオーバーライドが行われる必要がある場合、スーパークラスの 'override’キーワードを宣言する必要があります。

class sides {
   var corners = 4
   var description: String {
      return "\(corners) sides"
   }
}

let rectangle = sides()
print("Rectangle: \(rectangle.description)")

class pentagon: sides {
   override init() {
      super.init()
      corners = 5
   }
}

let bicycle = pentagon()
print("Pentagon: \(bicycle.description)")

プレイグラウンドを使用して上記のプログラムを実行すると、次の結果が得られます-

Rectangle: 4 sides
Pentagon: 5 sides

動作中の指定および便利な初期化子

class Planet {
   var name: String
   init(name: String) {
      self.name = name
   }
   convenience init() {
      self.init(name: "[No Planets]")
   }
}

let plName = Planet(name: "Mercury")
print("Planet name is: \(plName.name)")

let noplName = Planet()
print("No Planets like that: \(noplName.name)")

class planets: Planet {
   var count: Int
   init(name: String, count: Int) {
      self.count = count
      super.init(name: name)
   }
   override convenience init(name: String) {
      self.init(name: name, count: 1)
   }
}

プレイグラウンドを使用して上記のプログラムを実行すると、次の結果が得られます-

Planet name is: Mercury
No Planets like that: [No Planets]

Failable Initializer

ユーザーは、クラス、構造、または列挙値の定義中に初期化子の障害が発生したときに通知を受ける必要があります。 変数の初期化が原因で失敗することがあります-

  • 無効なパラメーター値。
  • 必要な外部ソースがありません。
  • 初期化の成功を妨げる条件。

初期化メソッドによってスローされた例外をキャッチするために、Swift 4は「failable initializer」と呼ばれる柔軟な初期化を生成し、構造体、クラス、または列挙メンバーの初期化中に何かが気付かれていないことをユーザーに通知します。 失敗可能な初期化子をキャッチするキーワードは「init?」です。 また、フェイル可能イニシャライザとフェイル不可イニシャライザを同じパラメータタイプと名前で定義することはできません。

struct studrecord {
   let stname: String
   init?(stname: String) {
      if stname.isEmpty {return nil }
      self.stname = stname
   }
}
let stmark = studrecord(stname: "Swing")

if let name = stmark {
   print("Student name is specified")
}
let blankname = studrecord(stname: "")

if blankname == nil {
   print("Student name is left blank")
}

プレイグラウンドを使用して上記のプログラムを実行すると、次の結果が得られます-

Student name is specified
Student name is left blank

列挙の失敗可能な初期化子

Swift 4言語は、列挙型メンバーが値の初期化を終了したときにユーザーに通知するために、列挙型のFailableイニシャライザーを使用する柔軟性を提供します。

enum functions {
   case a, b, c, d
   init?(funct: String) {
      switch funct {
      case "one":
         self = .a
      case "two":
         self = .b
      case "three":
         self = .c
      case "four":
         self = .d
      default:
         return nil
      }
   }
}
let result = functions(funct: "two")

if result != nil {
   print("With In Block Two")
}
let badresult = functions(funct: "five")

if badresult == nil {
   print("Block Does Not Exist")
}

プレイグラウンドを使用して上記のプログラムを実行すると、次の結果が得られます-

With In Block Two
Block Does Not Exist

クラスの失敗可能な初期化子

列挙型および構造体で宣言された失敗可能な初期化子は、その実装内の任意の状況で初期化の失敗を警告します。 ただし、クラスの失敗可能な初期化子は、保存されたプロパティが初期値に設定された後にのみ失敗を警告します。

class studrecord {
   let studname: String!
   init?(studname: String) {
      self.studname = studname
      if studname.isEmpty { return nil }
   }
}

if let stname = studrecord(studname: "Failable Initializers") {
   print("Module is \(stname.studname)")
}

プレイグラウンドを使用して上記のプログラムを実行すると、次の結果が得られます-

Module is Optional("Failable Initializers")

Failable Initializerのオーバーライド

初期化のように、ユーザーは、サブクラス内のスーパークラスのフェイル可能なイニシャライザーをオーバーライドする機能も備えています。 スーパークラスのフェイル可能初期化は、サブクラスのフェイル不可初期化子でオーバーライドすることもできます。

サブクラス初期化子は、失敗しないサブクラス初期化で失敗するスーパークラス初期化子をオーバーライドする場合、スーパークラス初期化子まで委任できません。

失敗しない初期化子は、失敗する初期化子に委任することはできません。

以下のプログラムは、フェイル可能イニシャライザーとフェイル不可イニシャライザーについて説明しています。

class Planet {
   var name: String

   init(name: String) {
      self.name = name
   }
   convenience init() {
      self.init(name: "[No Planets]")
   }
}
let plName = Planet(name: "Mercury")
print("Planet name is: \(plName.name)")

let noplName = Planet()
print("No Planets like that: \(noplName.name)")

class planets: Planet {
   var count: Int

   init(name: String, count: Int) {
      self.count = count
      super.init(name: name)
   }
   override convenience init(name: String) {
      self.init(name: name, count: 1)
   }
}

プレイグラウンドを使用して上記のプログラムを実行すると、次の結果が得られます-

Planet name is: Mercury
No Planets like that: [No Planets]

初期化! Failable Initializer

Swift 4は「init?」を提供しますオプションのインスタンス失敗可能イニシャライザを定義します。 特定のタイプ「init!」の暗黙的にアンラップされたオプションのインスタンスを定義するには指定されます。

struct studrecord {
let stname: String

   init!(stname: String) {
      if stname.isEmpty {return nil }
      self.stname = stname
   }
}
let stmark = studrecord(stname: "Swing")

if let name = stmark {
   print("Student name is specified")
}

let blankname = studrecord(stname: "")

if blankname == nil {
   print("Student name is left blank")
}

プレイグラウンドを使用して上記のプログラムを実行すると、次の結果が得られます-

Student name is specified
Student name is left blank

必要な初期化子

initialize 'required’キーワードの各サブクラスを宣言するには、init()関数の前に定義する必要があります。

class classA {
   required init() {
      var a = 10
      print(a)
   }
}

class classB: classA {
   required init() {
      var b = 30
      print(b)
   }
}

let res = classA()
let print = classB()

プレイグラウンドを使用して上記のプログラムを実行すると、次の結果が得られます-

10
30
10

Swift-初期化解除

クラスインスタンスの割り当てを解除する前に、メモリスペースの割り当てを解除するために「deinitializer」を呼び出す必要があります。 キーワード「deinit」は、システムリソースによって占有されているメモリ空間の割り当てを解除するために使用されます。 初期化解除は、クラスタイプでのみ使用できます。

メモリ空間の割り当てを解除するための初期化解除

Swift 4は、不要になったインスタンスを自動的に割り当て解除して、リソースを解放します。 Swift 4は、自動参照カウントで説明されているように、自動参照カウント(ARC)を介してインスタンスのメモリ管理を処理します。 通常、インスタンスの割り当てが解除されたときに、手動でクリーンアップを実行する必要はありません。 ただし、独自のリソースを使用している場合は、追加のクリーンアップを自分で実行する必要がある場合があります。 たとえば、ファイルを開いてデータを書き込むカスタムクラスを作成する場合、クラスインスタンスの割り当てを解除する前にファイルを閉じる必要があります。

var counter = 0;//for reference counting
class baseclass {
   init() {
      counter++;
   }
   deinit {
      counter--;
   }
}
var print: baseclass? = baseclass()

print(counter)
print = nil
print(counter)

プレイグラウンドを使用して上記のプログラムを実行すると、次の結果が得られます-

1
0

print = nilステートメントが省略されると、カウンターの値は初期化されないため、同じ値を保持します。

var counter = 0;//for reference counting

class baseclass {
   init() {
      counter++;
   }
   deinit {
      counter--;
   }
}
var print: baseclass? = baseclass()
print(counter)
print(counter)

プレイグラウンドを使用して上記のプログラムを実行すると、次の結果が得られます-

1
1

Swift-ARCの概要

メモリ管理機能とその使用は、Automatic Reference Counting(ARC)を通じてSwift 4言語で処理されます。 ARCは、システムリソースを初期化および初期化解除するために使用され、インスタンスが不要になったときに、クラスインスタンスによって使用されていたメモリスペースを解放します。 ARCは、コードインスタンス間の関係に関する情報を追跡して、メモリリソースを効果的に管理します。

ARCの機能

  • ARCは、init()によって新しいクラスインスタンスが作成されるたびに、情報を格納するためにメモリのチャンクを割り当てます。
  • インスタンスタイプとその値に関する情報はメモリに保存されます。
  • クラスインスタンスが不要になった場合、deinst()により、クラスインスタンスの保存と取得のためにメモリスペースが自動的に解放されます。
  • ARCは、現在参照しているクラスインスタンスのプロパティ、定数、および変数を追跡し、deinit()が未使用のインスタンスにのみ適用されるようにします。
  • ARCは、これらのクラスインスタンスプロパティ、定数、および変数への「強い参照」を維持して、クラスインスタンスが現在使用されている場合に割り当て解除を制限します。

ARCプログラム

class StudDetails {
   var stname: String!
   var mark: Int!

   init(stname: String, mark: Int) {
      self.stname = stname
      self.mark = mark
   }
   deinit {
      print("Deinitialized \(self.stname)")
      print("Deinitialized \(self.mark)")
   }
}

let stname = "Swift 4"
let mark = 98

print(stname)
print(mark)

プレイグラウンドを使用して上記のプログラムを実行すると、次の結果が得られます-

Swift 4
98

ARC強参照サイクルクラスインスタンス

class studmarks {
   let name: String
   var stud: student?

   init (name: String) {
      print("Initializing: \(name)")
      self.name = name
   }
   deinit {
      print("Deallocating: \(self.name)")
   }
}

class student {
   let name: String
   var strname: studmarks?

   init (name: String) {
      print("Initializing: \(name)")
      self.name = name
   }
   deinit {
      print("Deallocating: \(self.name)")
   }
}

var shiba: studmarks?
var mari: student?

shiba = studmarks(name: "Swift 4")
mari = student(name: "ARC")

shiba!.stud = mari
mari!.strname = shiba

プレイグラウンドを使用して上記のプログラムを実行すると、次の結果が得られます-

Initializing: Swift 4
Initializing: ARC

ARCの弱参照と非所有参照

クラス型プロパティには、強参照サイクルを解決する2つの方法があります-

  • 弱い参照
  • 所有されていない参照

これらの参照は、あるインスタンスが参照サイクルで他のインスタンスを参照できるようにするために使用されます。 その後、インスタンスは、強い参照サイクルを気にする代わりに、すべてのインスタンスを参照する場合があります。 いくつかのインスタンスが「nil」値を返す可能性があることをユーザーが知っている場合、弱参照を使用してそれを示すことができます。 インスタンスがnilではなく何かを返す場合、所有されていない参照で宣言します。

弱い参照プログラム

class module {
   let name: String
   init(name: String) { self.name = name }
   var sub: submodule?
   deinit { print("\(name) Is The Main Module") }
}

class submodule {
   let number: Int
   init(number: Int) { self.number = number }
   weak var topic: module?

   deinit { print("Sub Module with its topic number is \(number)") }
}

var toc: module?
var list: submodule?
toc = module(name: "ARC")
list = submodule(number: 4)
toc!.sub = list
list!.topic = toc

toc = nil
list = nil

プレイグラウンドを使用して上記のプログラムを実行すると、次の結果が得られます-

ARC Is The Main Module
Sub Module with its topic number is 4

未所有の参照プログラム

class student {
   let name: String
   var section: marks?
   init(name: String) {
      self.name = name
   }
   deinit { print("\(name)") }
}

class marks {
   let marks: Int
   unowned let stname: student

   init(marks: Int, stname: student) {
      self.marks = marks
      self.stname = stname
   }
   deinit { print("Marks Obtained by the student is \(marks)") }
}

var module: student?
module = student(name: "ARC")
module!.section = marks(marks: 98, stname: module!)
module = nil

プレイグラウンドを使用して上記のプログラムを実行すると、次の結果が得られます-

ARC
Marks Obtained by the student is 98

クロージャの強力な参照サイクル

特定のインスタンスをキャプチャするためにクラスインスタンスプロパティとクロージャーの本体にクロージャーを割り当てると、強い参照サイクルが発生する可能性があります。 クロージャーへの強い参照は、「self.someProperty」または「self.someMethod()」によって定義されます。 強参照サイクルは、クロージャの参照タイプとして使用されます。

class HTMLElement {
   let samplename: String
   let text: String?

   lazy var asHTML: () -> String = {
      if let text = self.text {
         return "<\(self.samplename)>\(text)</\(self.samplename)>"
      } else {
         return "<\(self.samplename)/>"
      }
   }
   init(samplename: String, text: String? = nil) {
      self.samplename = samplename
      self.text = text
   }
   deinit {
      print("\(samplename) is being deinitialized")
   }
}

var paragraph: HTMLElement? = HTMLElement(samplename: "p", text: "Welcome to Closure SRC")
print(paragraph!.asHTML())

プレイグラウンドを使用して上記のプログラムを実行すると、次の結果が得られます-

<p>Welcome to Closure SRC</p>

弱い参照と所有されていない参照

クロージャーとインスタンスが相互に参照する場合、ユーザーはクロージャー内のキャプチャを非所有参照として定義できます。 その場合、ユーザーが同時にインスタンスの割り当てを解除することはできません。 インスタンスがいつか「nil」値を返すと、弱いインスタンスを持つクロージャが定義されます。

class HTMLElement {
   let module: String
   let text: String?

   lazy var asHTML: () -> String = {
      [unowned self] in
      if let text = self.text {
         return "<\(self.module)>\(text)</\(self.module)>"
      } else {
         return "<\(self.module)/>"
      }
   }
   init(module: String, text: String? = nil) {
      self.module = module
      self.text = text
   }
   deinit {
      print("\(module) the deinit()")
   }
}

var paragraph: HTMLElement? = HTMLElement(module: "Inside", text: "ARC Weak References")
print(paragraph!.asHTML())
paragraph = nil

プレイグラウンドを使用して上記のプログラムを実行すると、次の結果が得られます-

<Inside>ARC Weak References</Inside>
Inside the deinit()

Swift-オプションの連鎖

「nil」の可能性のあるオプションのクエリ、プロパティ、サブスクリプト、およびメソッドの呼び出しのプロセスは、オプションの連鎖として定義されます。 オプションの連鎖は2つの値を返します-

  • オプションに「値」が含まれている場合、関連するプロパティ、メソッド、および添え字を呼び出すと値が返されます
  • オプションに 'nil’値が含まれ、その関連プロパティ、メソッド、および添え字がすべてnilを返す場合

メソッド、プロパティ、サブスクリプトへの複数のクエリはグループ化されるため、1つのチェーンの失敗はチェーン全体に影響し、「nil」値になります。

強制的なラップ解除の代替としてのオプションのチェーン

オプションのチェーンは、オプション値の後に「?」で指定されますオプションの値が値を返すときに、プロパティ、メソッド、または添え字を呼び出す。

Optional Chaining '?' Access to methods,properties and subscriptsOptional Chaining '!' to force Unwrapping
? is placed after the optional value to call property, method or subscript ! is placed after the optional value to call property, method or subscript to force unwrapping of value
Fails gracefully when the optional is 'nil' Forced unwrapping triggers a run time error when the optional is 'nil'

「!」を使用したオプションの連鎖プログラム

class ElectionPoll {
   var candidate: Pollbooth?
}

lass Pollbooth {
   var name = "MP"
}

let cand = ElectionPoll()
let candname = cand.candidate!.name

プレイグラウンドを使用して上記のプログラムを実行すると、次の結果が得られます-

fatal error: unexpectedly found nil while unwrapping an Optional value
0 Swift 4 0x0000000103410b68
llvm::sys::PrintStackTrace(__sFILE*) + 40
1 Swift 4 0x0000000103411054 SignalHandler(int) + 452
2 libsystem_platform.dylib 0x00007fff9176af1a _sigtramp + 26
3 libsystem_platform.dylib 0x000000000000000b _sigtramp + 1854492939
4 libsystem_platform.dylib 0x00000001074a0214 _sigtramp + 1976783636
5 Swift 4 0x0000000102a85c39
llvm::JIT::runFunction(llvm::Function*, std::__1::vector > const&) + 329
6 Swift 4 0x0000000102d320b3
llvm::ExecutionEngine::runFunctionAsMain(llvm::Function*,
std::__1::vector<std::__1::basic_string, std::__1::allocator >,
std::__1::allocator<std::__1::basic_string, std::__1::allocator > > > const&,
char const* const*) + 1523
7 Swift 4 0x000000010296e6ba Swift 4::RunImmediately(Swift
4::CompilerInstance&, std::__1::vector<std::__1::basic_string,
std::__1::allocator >, std::__1::allocator<std::__1::basic_string,
std::__1::allocator > > > const&, Swift 4::IRGenOptions&, Swift 4::SILOptions
const&) + 1066
8 Swift 4 0x000000010275764b frontend_main(llvm::ArrayRef,
char const*, void*) + 5275
9 Swift 4 0x0000000102754a6d main + 1677
10 libdyld.dylib 0x00007fff8bb9e5c9 start + 1
11 libdyld.dylib 0x000000000000000c start + 1950751300
Stack dump:
0. Program arguments:
/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/
usr/bin/Swift 4 -frontend -interpret - -target x86_64-apple-darwin14.0.0 -
target-cpu core2 -sdk
/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/
SDKs/MacOSX10.10.sdk -module-name main
/bin/sh: line 47: 15672 Done cat <<'SWIFT 4'
import Foundation
</std::__1::basic_string</std::__1::basic_string</std::__1::basic_string</std::
__1::basic_string

上記のプログラムは、クラス名として「選挙投票」を宣言し、メンバーシップ関数として「候補」を含んでいます。 サブクラスは「ポールブース」として宣言され、「名前」は「MP」として初期化されるメンバーシップ関数として宣言されます。 スーパークラスへの呼び出しは、オプションの「!」でインスタンス「cand」を作成することにより初期化されます。 値はその基本クラスで宣言されていないため、「nil」値が格納され、強制アンラップ手順によって致命的なエラーが返されます。

「?」を使用したオプションの連鎖プログラム

class ElectionPoll {
   var candidate: Pollbooth?
}

class Pollbooth {
   var name = "MP"
}
let cand = ElectionPoll()

if let candname = cand.candidate?.name {
   print("Candidate name is \(candname)")
} else {
   print("Candidate name cannot be retreived")
}

プレイグラウンドを使用して上記のプログラムを実行すると、次の結果が得られます-

Candidate name cannot be retreived

上記のプログラムは、クラス名として「選挙投票」を宣言し、メンバーシップ関数として「候補」を含んでいます。 サブクラスは「ポールブース」として宣言され、「名前」は「MP」として初期化されるメンバーシップ関数として宣言されます。 スーパークラスへの呼び出しは、オプションの「?」でインスタンス「cand」を作成することにより初期化されます。 値は基本クラスで宣言されていないため、「nil」値はelseハンドラーブロックによってコンソールに保存および出力されます。

オプションの連鎖およびプロパティへのアクセスのためのモデルクラスの定義

Swift 4言語は、複数のサブクラスをモデルクラスとして宣言するために、オプションのチェーンの概念も提供します。 この概念は、複雑なモデルを定義し、プロパティ、メソッド、およびサブスクリプトのサブプロパティにアクセスするのに非常に役立ちます。

class rectangle {
   var print: circle?
}

class circle {
   var area = [radius]()
   var cprint: Int {
      return area.count
   }
   subscript(i: Int) -> radius {
      get {
         return area[i]
      }
      set {
         area[i] = newValue
      }
   }
   func circleprint() {
      print("The number of rooms is \(cprint)")
   }
   var rectarea: circumference?
}

class radius {
   let radiusname: String
   init(radiusname: String) { self.radiusname = radiusname }
}

class circumference {
   var circumName: String?
   var circumNumber: String?
   var street: String?

   func buildingIdentifier() -> String? {
      if circumName != nil {
         return circumName
      } else if circumNumber != nil {
         return circumNumber
      } else {
         return nil
      }
   }
}

let rectname = rectangle()
if let rectarea = rectname.print?.cprint {
   print("Area of rectangle is \(rectarea)")
} else {
   print("Rectangle Area is not specified")
}

プレイグラウンドを使用して上記のプログラムを実行すると、次の結果が得られます-

Rectangle Area is not specified

オプションの連鎖によるメソッドの呼び出し

class rectangle {
   var print: circle?
}

class circle {
   var area = [radius]()
   var cprint: Int {
      return area.count
   }
   subscript(i: Int) -> radius {
      get {
         return area[i]
      }
      set {
         area[i] = newValue
      }
   }

   func circleprint() {
      print("Area of Circle is: \(cprint)")
   }
   var rectarea: circumference?
}

class radius {
   let radiusname: String
   init(radiusname: String) { self.radiusname = radiusname }
}

class circumference {
   var circumName: String?
   var circumNumber: String?
   var circumarea: String?

   func buildingIdentifier() -> String? {
      if circumName != nil {
         return circumName
      } else if circumNumber != nil {
         return circumNumber
      } else {
         return nil
      }
   }
}

let circname = rectangle()

if circname.print?.circleprint() != nil {
   print("Area of circle is specified)")
} else {
   print("Area of circle is not specified")
}

プレイグラウンドを使用して上記のプログラムを実行すると、次の結果が得られます-

Area of circle is not specified

circle()サブクラス内で宣言された関数circleprint()は、「circname」という名前のインスタンスを作成することによって呼び出されます。 関数は、値が含まれている場合は値を返します。それ以外の場合は、ステートメント「if circname.print?.circleprint()!= nil」をチェックして、ユーザー定義の印刷メッセージを返します。

オプションの連鎖による下付き文字へのアクセス

オプションの連鎖を使用して、添え字の値を設定および取得し、その添え字の呼び出しが値を返すかどうかを検証します。 「?」特定の添え字のオプション値にアクセスするために、添え字ブレースの前に配置されます。

プログラム1

class rectangle {
   var print: circle?
}

class circle {
   var area = [radius]()
   var cprint: Int {
      return area.count
   }
   subscript(i: Int) -> radius {
      get {
         return area[i]
      }
      set {
         area[i] = newValue
      }
   }
   func circleprint() {
      print("The number of rooms is \(cprint)")
   }
   var rectarea: circumference?
}

class radius {
   let radiusname: String
   init(radiusname: String) { self.radiusname =  radiusname }
}

class circumference {
   var circumName: String?
   var circumNumber: String?
   var circumarea: String?

   func buildingIdentifier() -> String? {
      if circumName != nil {
         return circumName
      } else if circumNumber != nil {
         return circumNumber
      } else {
         return nil
      }
   }
}

let circname = rectangle()

if let radiusName = circname.print?[0].radiusname {
   print("The first room name is \(radiusName).")
} else {
   print("Radius is not specified.")
}

プレイグラウンドを使用して上記のプログラムを実行すると、次の結果が得られます-

Radius is not specified.

上記のプログラムでは、メンバーシップ関数「radiusName」のインスタンス値は指定されていません。 したがって、関数へのプログラム呼び出しは、他の部分のみを返しますが、値を返すには、特定のメンバーシップ関数の値を定義する必要があります。

プログラム2

class rectangle {
   var print: circle?
}

class circle {
   var area = [radius]()
   var cprint: Int {
      return area.count
   }
   subscript(i: Int) -> radius {
      get {
         return area[i]
      }
      set {
         area[i] = newValue
      }
   }
   func circleprint() {
      print("The number of rooms is \(cprint)")
   }
   var rectarea: circumference?
}

class radius {
   let radiusname: String
   init(radiusname: String) { self.radiusname = radiusname }
}

class circumference {
   var circumName: String?
   var circumNumber: String?
   var circumarea: String?

   func buildingIdentifier() -> String? {
      if circumName != nil {
         return circumName
      } else if circumNumber != nil {
         return circumNumber
      } else {
         return nil
      }
   }
}

let circname = rectangle()
circname.print?[0] = radius(radiusname: "Diameter")
let printing = circle()

printing.area.append(radius(radiusname: "Units"))
printing.area.append(radius(radiusname: "Meter"))
circname.print = printing

if let radiusName = circname.print?[0].radiusname {
   print("Radius is measured in \(radiusName).")
} else {
   print("Radius is not specified.")
}

プレイグラウンドを使用して上記のプログラムを実行すると、次の結果が得られます-

Radius is measured in Units.

上記のプログラムでは、メンバーシップ関数「radiusName」のインスタンス値が指定されています。 したがって、関数のプログラム呼び出しは値を返すようになります。

オプションタイプの添え字へのアクセス

class rectangle {
   var print: circle?
}

class circle {
   var area = [radius]()
   var cprint: Int {
      return area.count
   }

   subscript(i: Int) -> radius {
      get {
         return area[i]
      }
      set {
         area[i] = newValue
      }
   }
   func circleprint() {
      print("The number of rooms is \(cprint)")
   }
   var rectarea: circumference?
}

class radius {
   let radiusname: String
   init(radiusname: String) { self.radiusname = radiusname }
}

class circumference {
   var circumName: String?
   var circumNumber: String?
   var circumarea: String?

   func buildingIdentifier() -> String? {
      if circumName != nil {
         return circumName
      } else if circumNumber != nil {
         return circumNumber
      } else {
         return nil
      }
   }
}

let circname = rectangle()
circname.print?[0] = radius(radiusname: "Diameter")

let printing = circle()
printing.area.append(radius(radiusname: "Units"))
printing.area.append(radius(radiusname: "Meter"))
circname.print = printing

var area = ["Radius": [35, 45, 78, 101], "Circle": [90, 45, 56]]
area["Radius"]?[1] = 78
area["Circle"]?[1]--

print(area["Radius"]?[0])
print(area["Radius"]?[1])
print(area["Radius"]?[2])
print(area["Radius"]?[3])

print(area["Circle"]?[0])
print(area["Circle"]?[1])
print(area["Circle"]?[2])

プレイグラウンドを使用して上記のプログラムを実行すると、次の結果が得られます-

Optional(35)
Optional(78)
Optional(78)
Optional(101)
Optional(90)
Optional(44)
Optional(56)

添え字のオプション値には、添え字の値を参照することでアクセスできます。 subscript [0]、subscript [1]などとしてアクセスできます。 「半径」のデフォルトの添え字の値は、最初に[35、45、78、101]として割り当てられ、 '円’のデフォルトの添え字値[90、45、56]]に割り当てられます。 次に、添え字の値がRadius [0]から78、Circle [1]から45に変更されます。

複数レベルの連鎖のリンク

オプションの連鎖により、複数のサブクラスをそのスーパークラスのメソッド、プロパティ、サブスクリプトとリンクすることもできます。

オプションの複数のチェーンをリンクすることができます-

タイプの取得がオプションでない場合、オプションのチェーンはオプションの値を返します。 たとえば、オプションの連鎖による文字列の場合、文字列が返されますか? 値

class rectangle {
   var print: circle?
}

class circle {
   var area = [radius]()
   var cprint: Int {
      return area.count
   }
   subscript(i: Int) -> radius {
      get {
         return area[i]
      }
      set {
         area[i] = newValue
      }
   }
   func circleprint() {
      print("The number of rooms is \(cprint)")
   }
   var rectarea: circumference?
}

class radius {
   let radiusname: String
   init(radiusname: String) { self.radiusname = radiusname }
}

class circumference {
   var circumName: String?
   var circumNumber: String?
   var circumarea: String?

   func buildingIdentifier() -> String? {
      if circumName != nil {
         return circumName
      } else if circumNumber != nil {
         return circumNumber
      } else {
         return nil
      }
   }
}

let circname = rectangle()

if let radiusName = circname.print?[0].radiusname {
   print("The first room name is \(radiusName).")
} else {
   print("Radius is not specified.")
}

プレイグラウンドを使用して上記のプログラムを実行すると、次の結果が得られます-

Radius is not specified.

上記のプログラムでは、メンバーシップ関数「radiusName」のインスタンス値は指定されていません。 したがって、関数を呼び出すプログラムは、他の部分のみを返しますが、値を返すには、特定のメンバーシップ関数の値を定義する必要があります。

取得タイプがすでにオプションである場合、オプションの連鎖もオプションの値を返します。 たとえば、String? オプションのチェーンを介してアクセスすると、文字列が返されますか? 値..

class rectangle {
   var print: circle?
}

class circle {
   var area = [radius]()
   var cprint: Int {
      return area.count
   }
   subscript(i: Int) -> radius {
      get {
         return area[i]
      }
      set {
         area[i] = newValue
      }
   }
   func circleprint() {
      print("The number of rooms is \(cprint)")
   }
   var rectarea: circumference?
}

class radius {
   let radiusname: String
   init(radiusname: String) { self.radiusname = radiusname }
}

class circumference {
   var circumName: String?
   var circumNumber: String?
   var circumarea: String?

   func buildingIdentifier() -> String? {
      if circumName != nil {
         return circumName
      } else if circumNumber != nil {
         return circumNumber
      } else {
         return nil
      }
   }
}

let circname = rectangle()
circname.print?[0] = radius(radiusname: "Diameter")
let printing = circle()

printing.area.append(radius(radiusname: "Units"))
printing.area.append(radius(radiusname: "Meter"))
circname.print = printing

if let radiusName = circname.print?[0].radiusname {
   print("Radius is measured in \(radiusName).")
} else {
   print("Radius is not specified.")
}

プレイグラウンドを使用して上記のプログラムを実行すると、次の結果が得られます-

Radius is measured in Units.

上記のプログラムでは、メンバーシップ関数「radiusName」のインスタンス値が指定されています。 したがって、関数のプログラム呼び出しは値を返すようになります。

オプションの戻り値を持つメソッドのチェーン

オプションのチェーンは、サブクラスで定義されたメソッドにもアクセスするために使用されます。

class rectangle {
   var print: circle?
}

class circle {
   var area = [radius]()
   var cprint: Int {
      return area.count
   }
   subscript(i: Int) -> radius {
      get {
         return area[i]
      }
      set {
         area[i] = newValue
      }
   }
   func circleprint() {
      print("Area of Circle is: \(cprint)")
   }
   var rectarea: circumference?
}

class radius {
   let radiusname: String
   init(radiusname: String) { self.radiusname = radiusname }
}

class circumference {
   var circumName: String?
   var circumNumber: String?
   var circumarea: String?

   func buildingIdentifier() -> String? {
      if circumName != nil {
         return circumName
      } else if circumNumber != nil {
         return circumNumber
      } else {
         return nil
      }
   }
}

let circname = rectangle()

if circname.print?.circleprint() != nil {
   print("Area of circle is specified)")
} else {
   print("Area of circle is not specified")
}

プレイグラウンドを使用して上記のプログラムを実行すると、次の結果が得られます-

Area of circle is not specified

スイフト-型キャスト

インスタンスの型を検証するために、「型キャスト」がSwift 4言語で機能します。 インスタンスタイプが特定のスーパークラスまたはサブクラスに属しているか、独自の階層で定義されているかを確認するために使用されます。

Swift 4型キャストは、値の型と「as」をチェックし、型の値を別の型にキャストする2つの演算子「is」を提供します。 型キャストは、インスタンスタイプが特定のプロトコル適合規格に従っているかどうかもチェックします。

クラス階層の定義

型キャストは、インスタンスのタイプをチェックして、特定のクラスタイプに属しているかどうかを確認するために使用されます。 また、クラスとそのサブクラスの階層をチェックして、それらのインスタンスをチェックおよびキャストし、同じ階層として作成します。

class Subjects {
   var physics: String
   init(physics: String) {
      self.physics = physics
   }
}

class Chemistry: Subjects {
   var equations: String
   init(physics: String, equations: String) {
      self.equations = equations
      super.init(physics: physics)
   }
}

class Maths: Subjects {
   var formulae: String
   init(physics: String, formulae: String) {
      self.formulae = formulae
      super.init(physics: physics)
   }
}

let sa = [ Chemistry(physics: "solid physics", equations: "Hertz"),
   Maths(physics: "Fluid Dynamics", formulae: "Giga Hertz")]

let samplechem = Chemistry(physics: "solid physics", equations: "Hertz")
print("Instance physics is: \(samplechem.physics)")
print("Instance equation is: \(samplechem.equations)")

let samplemaths = Maths(physics: "Fluid Dynamics", formulae: "Giga Hertz")
print("Instance physics is: \(samplemaths.physics)")
print("Instance formulae is: \(samplemaths.formulae)")

プレイグラウンドを使用して上記のプログラムを実行すると、次の結果が得られます-

Instance physics is: solid physics
Instance equation is: Hertz
Instance physics is: Fluid Dynamics
Instance formulae is: Giga Hertz

型チェック

型チェックは「is」演算子で行われます。 「is」型チェック演算子は、インスタンスが特定のサブクラス型に属するかどうかをチェックし、そのインスタンスに属する場合は「true」を返し、そうでない場合は「false」を返します。

class Subjects {
   var physics: String
   init(physics: String) {
      self.physics = physics
   }
}

class Chemistry: Subjects {
   var equations: String
   init(physics: String, equations: String) {
      self.equations = equations
      super.init(physics: physics)
   }
}

class Maths: Subjects {
   var formulae: String
   init(physics: String, formulae: String) {
      self.formulae = formulae
      super.init(physics: physics)
   }
}

let sa = [
   Chemistry(physics: "solid physics", equations: "Hertz"),
   Maths(physics: "Fluid Dynamics", formulae: "Giga Hertz"),
   Chemistry(physics: "Thermo physics", equations: "Decibels"),
   Maths(physics: "Astro Physics", formulae: "MegaHertz"),
   Maths(physics: "Differential Equations", formulae: "Cosine Series")]

let samplechem = Chemistry(physics: "solid physics", equations: "Hertz")
print("Instance physics is: \(samplechem.physics)")
print("Instance equation is: \(samplechem.equations)")

let samplemaths = Maths(physics: "Fluid Dynamics", formulae: "Giga Hertz")
print("Instance physics is: \(samplemaths.physics)")
print("Instance formulae is: \(samplemaths.formulae)")

var chemCount = 0
var mathsCount = 0
for item in sa {
   if item is Chemistry {
      ++chemCount
   } else if item is Maths {
      ++mathsCount
   }
}

print("Subjects in chemistry contains \(chemCount) topics and maths contains \(mathsCount) topics")

プレイグラウンドを使用して上記のプログラムを実行すると、次の結果が得られます-

Instance physics is: solid physics
Instance equation is: Hertz
Instance physics is: Fluid Dynamics
Instance formulae is: Giga Hertz
Subjects in chemistry contains 2 topics and maths contains 3 topics

ダウンキャスト

サブクラスタイプのダウンキャストは、2つの演算子(as? そしてas!)。 'as?'値がnilを返す場合、オプションの値を返します。 ダウンキャストの成功を確認するために使用されます。

'として!'ダウンキャストがnil値を返す場合、オプションのチェーンで説明されているように、強制的にアンラッピングを返します。 ダウンキャストに失敗した場合にランタイムエラーをトリガーするために使用されます

class Subjects {
   var physics: String
   init(physics: String) {
      self.physics = physics
   }
}

class Chemistry: Subjects {
   var equations: String
   init(physics: String, equations: String) {
      self.equations = equations
      super.init(physics: physics)
   }
}

class Maths: Subjects {
   var formulae: String
   init(physics: String, formulae: String) {
      self.formulae = formulae
      super.init(physics: physics)
   }
}

let sa = [
   Chemistry(physics: "solid physics", equations: "Hertz"),
   Maths(physics: "Fluid Dynamics", formulae: "Giga Hertz"),
   Chemistry(physics: "Thermo physics", equations: "Decibels"),
   Maths(physics: "Astro Physics", formulae: "MegaHertz"),
   Maths(physics: "Differential Equations", formulae: "Cosine Series")]

let samplechem = Chemistry(physics: "solid physics", equations: "Hertz")
print("Instance physics is: \(samplechem.physics)")
print("Instance equation is: \(samplechem.equations)")

let samplemaths = Maths(physics: "Fluid Dynamics", formulae: "Giga Hertz")
print("Instance physics is: \(samplemaths.physics)")
print("Instance formulae is: \(samplemaths.formulae)")

var chemCount = 0
var mathsCount = 0

for item in sa {
   if let print = item as? Chemistry {
      print("Chemistry topics are: '\(print.physics)', \(print.equations)")
   } else if let example = item as? Maths {
      print("Maths topics are: '\(example.physics)', \(example.formulae)")
   }
}

プレイグラウンドを使用して上記のプログラムを実行すると、次の結果が得られます-

Instance physics is: solid physics
Instance equation is: Hertz
Instance physics is: Fluid Dynamics
Instance formulae is: Giga Hertz
Chemistry topics are: 'solid physics', Hertz
Maths topics are: 'Fluid Dynamics', Giga Hertz
Chemistry topics are: 'Thermo physics', Decibels
Maths topics are: 'Astro Physics', MegaHertz
Maths topics are: 'Differential Equations', Cosine Series

型キャスト:任意のオブジェクト

キーワード「Any」は、関数タイプを含む任意のタイプに属するインスタンスを表すために使用されます。

class Subjects {
   var physics: String
   init(physics: String) {
      self.physics = physics
   }
}

class Chemistry: Subjects {
   var equations: String
   init(physics: String, equations: String) {
      self.equations = equations
      super.init(physics: physics)
   }
}

class Maths: Subjects {
   var formulae: String
   init(physics: String, formulae: String) {
      self.formulae = formulae
      super.init(physics: physics)
   }
}

let sa = [
   Chemistry(physics: "solid physics", equations: "Hertz"),
   Maths(physics: "Fluid Dynamics", formulae: "Giga Hertz"),
   Chemistry(physics: "Thermo physics", equations: "Decibels"),
   Maths(physics: "Astro Physics", formulae: "MegaHertz"),
   Maths(physics: "Differential Equations", formulae: "Cosine Series")]

let samplechem = Chemistry(physics: "solid physics", equations: "Hertz")
print("Instance physics is: \(samplechem.physics)")
print("Instance equation is: \(samplechem.equations)")

let samplemaths = Maths(physics: "Fluid Dynamics", formulae: "Giga Hertz")
print("Instance physics is: \(samplemaths.physics)")
print("Instance formulae is: \(samplemaths.formulae)")

var chemCount = 0
var mathsCount = 0

for item in sa {
   if let print = item as? Chemistry {
      print("Chemistry topics are: '\(print.physics)', \(print.equations)")
   } else if let example = item as? Maths {
      print("Maths topics are: '\(example.physics)', \(example.formulae)")
   }
}

var exampleany = [Any]()

exampleany.append(12)
exampleany.append(3.14159)
exampleany.append("Example for Any")
exampleany.append(Chemistry(physics: "solid physics", equations: "Hertz"))

for print in exampleany {
   switch print {
      case let someInt as Int:
         print("Integer value is \(someInt)")
      case let someDouble as Double where someDouble > 0:
         print("Pi value is \(someDouble)")
      case let someString as String:
         print("\(someString)")
      case let phy as Chemistry:
         print("Topics '\(phy.physics)', \(phy.equations)")
      default:
         print("None")
   }
}

プレイグラウンドを使用して上記のプログラムを実行すると、次の結果が得られます-

Instance physics is: solid physics
Instance equation is: Hertz
Instance physics is: Fluid Dynamics
Instance formulae is: Giga Hertz
Chemistry topics are: 'solid physics', Hertz
Maths topics are: 'Fluid Dynamics', Giga Hertz
Chemistry topics are: 'Thermo physics', Decibels
Maths topics are: 'Astro Physics', MegaHertz
Maths topics are: 'Differential Equations', Cosine Series
Integer value is 12
Pi value is 3.14159
Example for Any
Topics 'solid physics', Hertz

AnyObject

任意のクラスタイプのインスタンスを表すために、「AnyObject」キーワードが使用されます。

class Subjects {
   var physics: String
   init(physics: String) {
      self.physics = physics
   }
}

class Chemistry: Subjects {
   var equations: String
   init(physics: String, equations: String) {
      self.equations = equations
      super.init(physics: physics)
   }
}

class Maths: Subjects {
   var formulae: String
   init(physics: String, formulae: String) {
      self.formulae = formulae
      super.init(physics: physics)
   }
}

let saprint: [AnyObject] = [Chemistry(physics: "solid physics", equations: "Hertz"),
   Maths(physics: "Fluid Dynamics", formulae: "Giga Hertz"),
   Chemistry(physics: "Thermo physics", equations: "Decibels"),
   Maths(physics: "Astro Physics", formulae: "MegaHertz"),
   Maths(physics: "Differential Equations", formulae: "Cosine Series")]

let samplechem = Chemistry(physics: "solid physics", equations: "Hertz")
print("Instance physics is: \(samplechem.physics)")
print("Instance equation is: \(samplechem.equations)")

let samplemaths = Maths(physics: "Fluid Dynamics", formulae: "Giga Hertz")
print("Instance physics is: \(samplemaths.physics)")
print("Instance formulae is: \(samplemaths.formulae)")

var chemCount = 0
var mathsCount = 0

for item in saprint {
   if let print = item as? Chemistry {
      print("Chemistry topics are: '\(print.physics)', \(print.equations)")
   } else if let example = item as? Maths {
      print("Maths topics are: '\(example.physics)', \(example.formulae)")
   }
}

var exampleany = [Any]()
exampleany.append(12)
exampleany.append(3.14159)
exampleany.append("Example for Any")
exampleany.append(Chemistry(physics: "solid physics", equations: "Hertz"))

for print in exampleany {
   switch print {
      case let someInt as Int:
         print("Integer value is \(someInt)")
      case let someDouble as Double where someDouble > 0:
         print("Pi value is \(someDouble)")
      case let someString as String:
         print("\(someString)")
      case let phy as Chemistry:
         print("Topics '\(phy.physics)', \(phy.equations)")
      default:
         print("None")
   }
}

プレイグラウンドを使用して上記のプログラムを実行すると、次の結果が得られます-

Instance physics is: solid physics
Instance equation is: Hertz
Instance physics is: Fluid Dynamics
Instance formulae is: Giga Hertz
Chemistry topics are: 'solid physics', Hertz
Maths topics are: 'Fluid Dynamics', Giga Hertz
Chemistry topics are: 'Thermo physics', Decibels
Maths topics are: 'Astro Physics', MegaHertz
Maths topics are: 'Differential Equations', Cosine Series
Integer value is 12
Pi value is 3.14159
Example for Any
Topics 'solid physics', Hertz

Swift-拡張機能

既存のクラス、構造、または列挙型の機能は、拡張機能を使用して追加できます。 タイプ機能は拡張機能で追加できますが、拡張機能では機能をオーバーライドできません。

  • Swift拡張機能*-
  • 計算プロパティと計算タイププロパティの追加
  • インスタンスおよびタイプメソッドの定義。
  • 新しい初期化子の提供。
  • 添え字の定義
  • 新しいネストされた型の定義と使用 *既存のタイプをプロトコルに準拠させる

拡張は、キーワード 'extension’で宣言されます

構文

extension SomeType {
  //new functionality can be added here
}

既存のタイプを拡張機能で追加して、プロトコルの標準として作成することもできます。その構文は、クラスまたは構造の構文に似ています。

extension SomeType: SomeProtocol, AnotherProtocol {
  //protocol requirements is described here
}

計算プロパティ

計算された「インスタンス」および「タイプ」プロパティは、拡張機能を使用して拡張することもできます。

extension Int {
   var add: Int {return self + 100 }
   var sub: Int { return self - 10 }
   var mul: Int { return self* 10 }
   var div: Int { return self/5 }
}

let addition = 3.add
print("Addition is \(addition)")

let subtraction = 120.sub
print("Subtraction is \(subtraction)")

let multiplication = 39.mul
print("Multiplication is \(multiplication)")

let division = 55.div
print("Division is \(division)")

let mix = 30.add + 34.sub
print("Mixed Type is \(mix)")

プレイグラウンドを使用して上記のプログラムを実行すると、次の結果が得られます-

Addition is 103
Subtraction is 110
Multiplication is 390
Division is 11
Mixed Type is 154

初期化子

Swift 4は、拡張機能によって既存の型に新しい初期化子を追加する柔軟性を提供します。 ユーザーは独自のカスタムタイプを追加して、すでに定義されているタイプを拡張でき、追加の初期化オプションも可能です。 拡張機能はinit()のみをサポートします。 deinit()は拡張機能ではサポートされていません。

struct sum {
   var num1 = 100, num2 = 200
}

struct diff {
   var no1 = 200, no2 = 100
}

struct mult {
   var a = sum()
   var b = diff()
}

let calc = mult()
print ("Inside mult block \(calc.a.num1, calc.a.num2)")
print("Inside mult block \(calc.b.no1, calc.b.no2)")

let memcalc = mult(a: sum(num1: 300, num2: 500),b: diff(no1: 300, no2: 100))
print("Inside mult block \(memcalc.a.num1, memcalc.a.num2)")
print("Inside mult block \(memcalc.b.no1, memcalc.b.no2)")

extension mult {
   init(x: sum, y: diff) {
      let X = x.num1 + x.num2
      let Y = y.no1 + y.no2
   }
}

let a = sum(num1: 100, num2: 200)
print("Inside Sum Block:\( a.num1, a.num2)")

let b = diff(no1: 200, no2: 100)
print("Inside Diff Block: \(b.no1, b.no2)")

プレイグラウンドを使用して上記のプログラムを実行すると、次の結果が得られます-

Inside mult block (100, 200)
Inside mult block (200, 100)
Inside mult block (300, 500)
Inside mult block (300, 100)
Inside Sum Block:(100, 200)
Inside Diff Block: (200, 100)

方法

拡張機能の助けを借りて、サブクラスに新しいインスタンスメソッドと型メソッドをさらに追加できます。

extension Int {
   func topics(summation: () -> ()) {
      for _ in 0..<self {
         summation()
      }
   }
}

4.topics(summation: {
   print("Inside Extensions Block")
})

3.topics(summation: {
   print("Inside Type Casting Block")
})

プレイグラウンドを使用して上記のプログラムを実行すると、次の結果が得られます-

Inside Extensions Block
Inside Extensions Block
Inside Extensions Block
Inside Extensions Block
Inside Type Casting Block
Inside Type Casting Block
Inside Type Casting Block

topic()関数は、 '(summation:()→())'型の引数を取り、関数が引数を取らず、値を返さないことを示します。 その関数を複数回呼び出すには、forブロックが初期化され、topic()でメソッドの呼び出しが初期化されます。

インスタンスメソッドの変更

インスタンスメソッドは、拡張機能として宣言されたときに変更することもできます。

自己またはそのプロパティを変更する構造および列挙メソッドは、元の実装のメソッドを変更するのと同様に、インスタンスメソッドを変更としてマークする必要があります。

extension Double {
   mutating func square() {
      let pi = 3.1415
      self = pi *self* self
   }
}

var Trial1 = 3.3
Trial1.square()
print("Area of circle is: \(Trial1)")

var Trial2 = 5.8
Trial2.square()
print("Area of circle is: \(Trial2)")

var Trial3 = 120.3
Trial3.square()
print("Area of circle is: \(Trial3)")

プレイグラウンドを使用して上記のプログラムを実行すると、次の結果が得られます-

Area of circle is: 34.210935
Area of circle is: 105.68006
Area of circle is: 45464.070735

下付き文字

拡張機能を使用して、すでに宣言されているインスタンスに新しい添え字を追加することもできます。

extension Int {
   subscript(var multtable: Int) -> Int {
      var no1 = 1
      while multtable > 0 {
         no1 *= 10
         --multtable
      }
      return (self/no1) % 10
   }
}

print(12[0])
print(7869[1])
print(786543[2])

プレイグラウンドを使用して上記のプログラムを実行すると、次の結果が得られます-

2
6
5

入れ子になった型

クラス、構造、および列挙インスタンスのネストされた型は、拡張機能を使用して拡張することもできます。

extension Int {
   enum calc {
      case add
      case sub
      case mult
      case div
      case anything
   }
   var print: calc {
      switch self {
         case 0:
            return .add
         case 1:
            return .sub
         case 2:
            return .mult
         case 3:
            return .div
         default:
            return .anything
      }
   }
}

func result(numb: [Int]) {
   for i in numb {
      switch i.print {
         case .add:
            print(" 10 ")
         case .sub:
            print(" 20 ")
         case .mult:
            print(" 30 ")
         case .div:
            print(" 40 ")
         default:
            print(" 50 ")
      }
   }
}
result(numb: [0, 1, 2, 3, 4, 7])

プレイグラウンドを使用して上記のプログラムを実行すると、次の結果が得られます-

10
20
30
40
50
50

Swift-プロトコル

プロトコルは、メソッド、プロパティ、およびその他の要件機能の青写真を提供します。 実装ではなく、メソッドまたはプロパティのスケルトンとして記述されています。 メソッドとプロパティの実装は、クラス、関数、列挙を定義することでさらに実行できます。 プロトコルの適合性は、プロトコルの要件を満たすメソッドまたはプロパティとして定義されます。

構文

プロトコルも、クラス、構造、および列挙の構文と同様の構文に従います-

protocol SomeProtocol {
  //protocol definition
}

プロトコルは、クラス、構造、または列挙型の名前の後に宣言されます。 単一および複数のプロトコル宣言も可能です。 複数のプロトコルが定義されている場合、コンマで区切る必要があります。

struct SomeStructure: Protocol1, Protocol2 {
  //structure definition
}

スーパークラスにプロトコルを定義する必要がある場合、プロトコル名はスーパークラス名の後にカンマを付けてください。

class SomeClass: SomeSuperclass, Protocol1, Protocol2 {
  //class definition
}

プロパティとメソッドの要件

プロトコルは、特定のクラスタイププロパティまたはインスタンスプロパティを指定するために使用されます。 格納されたプロパティであるか計算されたプロパティであるかを指定するのではなく、タイプまたはインスタンスのプロパティのみを指定します。 また、プロパティが「gettable」か「settable」かを指定するために使用されます。

プロパティ要件は、プロパティ変数として「var」キーワードによって宣言されます。 \ {get set}は、型宣言後にgettableおよびsettableプロパティを宣言するために使用されます。 Gettableは、型宣言の後に\ {get}プロパティによって言及されます。

protocol classa {
   var marks: Int { get set }
   var result: Bool { get }

   func attendance() -> String
   func markssecured() -> String
}

protocol classb: classa {
   var present: Bool { get set }
   var subject: String { get set }
   var stname: String { get set }
}

class classc: classb {
   var marks = 96
   let result = true
   var present = false
   var subject = "Swift 4 Protocols"
   var stname = "Protocols"

   func attendance() -> String {
      return "The \(stname) has secured 99% attendance"
   }
   func markssecured() -> String {
      return "\(stname) has scored \(marks)"
   }
}

let studdet = classc()
studdet.stname = "Swift 4"
studdet.marks = 98
studdet.markssecured()

print(studdet.marks)
print(studdet.result)
print(studdet.present)
print(studdet.subject)
print(studdet.stname)

プレイグラウンドを使用して上記のプログラムを実行すると、次の結果が得られます-

98
true
false
Swift 4 Protocols
Swift 4

変更メソッドの要件

protocol daysofaweek {
   mutating func print()
}

enum days: daysofaweek {
   case sun, mon, tue, wed, thurs, fri, sat
   mutating func print() {
      switch self {
         case sun:
            self = sun
            print("Sunday")
         case mon:
            self = mon
            print("Monday")
         case tue:
            self = tue
            print("Tuesday")
         case wed:
            self = wed
            print("Wednesday")
         case mon:
            self = thurs
            print("Thursday")
         case tue:
            self = fri
            print("Friday")
         case sat:
            self = sat
            print("Saturday")
         default:
            print("NO Such Day")
      }
   }
}

var res = days.wed
res.print()

プレイグラウンドを使用して上記のプログラムを実行すると、次の結果が得られます-

Wednesday

初期化子の要件

Swingを使用すると、ユーザーはプロトコルを初期化して、通常の初期化子と同様の型の準拠に従うことができます。

構文

protocol SomeProtocol {
   init(someParameter: Int)
}

例えば

protocol tcpprotocol {
   init(aprot: Int)
}

プロトコル初期化子要件のクラス実装

指定されたまたは便利な初期化子により、ユーザーは予約された「必須」キーワードによってプロトコルを初期化して標準に準拠させることができます。

class SomeClass: SomeProtocol {
   required init(someParameter: Int) {
     //initializer implementation statements
   }
}

protocol tcpprotocol {
   init(aprot: Int)
}

class tcpClass: tcpprotocol {
   required init(aprot: Int) {
   }
}

プロトコルの適合性は、「必須」修飾子によって明示的または継承された実装のすべてのサブクラスで保証されます。

サブクラスがスーパークラスの初期化要件をオーバーライドする場合、「override」修飾子キーワードで指定されます。

protocol tcpprotocol {
   init(no1: Int)
}

class mainClass {
   var no1: Int       //local storage
   init(no1: Int) {
      self.no1 = no1 //initialization
   }
}

class subClass: mainClass, tcpprotocol {
   var no2: Int
   init(no1: Int, no2 : Int) {
      self.no2 = no2
      super.init(no1:no1)
   }
  //Requires only one parameter for convenient method
   required override convenience init(no1: Int) {
      self.init(no1:no1, no2:0)
   }
}

let res = mainClass(no1: 20)
let print = subClass(no1: 30, no2: 50)

print("res is: \(res.no1)")
print("res is: \(print.no1)")
print("res is: \(print.no2)")

プレイグラウンドを使用して上記のプログラムを実行すると、次の結果が得られます-

res is: 20
res is: 30
res is: 50

タイプとしてのプロトコル

プロトコルに機能を実装する代わりに、それらは関数、クラス、メソッドなどの型として使用されます。

プロトコルは、次のタイプとしてアクセスできます-

  • 関数、メソッド、またはパラメーターまたは戻り値の型として初期化
  • 定数、変数またはプロパティ
  • 配列としての辞書、辞書、またはその他のコンテナ
protocol Generator {
   typealias members
   func next() -> members?
}

var items = [10,20,30].generate()
while let x = items.next() {
   print(x)
}

for lists in map([1,2,3], {i in i*5}) {
   print(lists)
}

print([100,200,300])
print(map([1,2,3], {i in i*10}))

プレイグラウンドを使用して上記のプログラムを実行すると、次の結果が得られます-

10
20
30
5
10
15
[100, 200, 300]
[10, 20, 30]

拡張機能によるプロトコル適合性の追加

拡張を利用することにより、既存のタイプを採用して新しいプロトコルに適合させることができます。 拡張機能を使用して、既存のタイプに新しいプロパティ、メソッド、および添え字を追加できます。

protocol AgeClasificationProtocol {
   var age: Int { get }
   func agetype() -> String
}
class Person {
   let firstname: String
   let lastname: String
   var age: Int

   init(firstname: String, lastname: String) {
      self.firstname = firstname
      self.lastname = lastname
      self.age = 10
   }
}

extension Person : AgeClasificationProtocol {
   func fullname() -> String {
      var c: String
      c = firstname + " " + lastname
      return c
   }
   func agetype() -> String {
      switch age {
         case 0...2:
            return "Baby"
         case 2...12:
            return "Child"
         case 13...19:
            return "Teenager"
         case let x where x > 65:
            return "Elderly"
         default:
            return "Normal"
      }
   }
}

プロトコル継承

Swift 4では、プロトコルは定義されたプロパティからプロパティを継承できます。 クラスの継承と似ていますが、複数の継承されたプロトコルをコンマで区切ってリストすることを選択します。

protocol classa {
   var no1: Int { get set }
   func calc(sum: Int)
}
protocol result {
   func print(target: classa)
}
class student2: result {
   func print(target: classa) {
      target.calc(sum: 1)
   }
}
class classb: result {
   func print(target: classa) {
      target.calc(sum: 5)
   }
}

class student: classa {
   var no1: Int = 10

   func calc(sum: Int) {
      no1 -= sum
      print("Student attempted \(sum) times to pass")

      if no1 <= 0 {
         print("Student is absent for exam")
      }
   }
}

class Player {
   var stmark: result!

   init(stmark: result) {
      self.stmark = stmark
   }
   func print(target: classa) {
      stmark.print(target: target)
   }
}

var marks = Player(stmark: student2())
var marksec = student()

marks.print(target: marksec)
marks.print(target: marksec)
marks.print(target: marksec)
marks.stmark = classb()
marks.print(target: marksec)
marks.print(target: marksec)
marks.print(target: marksec)

プレイグラウンドを使用して上記のプログラムを実行すると、次の結果が得られます-

Student attempted 1 times to pass
Student attempted 1 times to pass
Student attempted 1 times to pass
Student attempted 5 times to pass
Student attempted 5 times to pass
Student is absent for exam
Student attempted 5 times to pass
Student is absent for exam

クラスのみのプロトコル

プロトコルが定義されており、ユーザーがクラスでプロトコルを定義する場合、最初にクラスを定義し、その後にプロトコルの継承リストを追加して追加する必要があります。

protocol tcpprotocol {
   init(no1: Int)
}
class mainClass {
   var no1: Int       //local storage
   init(no1: Int) {
      self.no1 = no1 //initialization
   }
}
class subClass: mainClass, tcpprotocol {
   var no2: Int
   init(no1: Int, no2 : Int) {
      self.no2 = no2
      super.init(no1:no1)
   }

  //Requires only one parameter for convenient method
   required override convenience init(no1: Int) {
      self.init(no1:no1, no2:0)
   }
}

let res = mainClass(no1: 20)
let print = subClass(no1: 30, no2: 50)

print("res is: \(res.no1)")
print("res is: \(print.no1)")
print("res is: \(print.no2)")

プレイグラウンドを使用して上記のプログラムを実行すると、次の結果が得られます-

res is: 20
res is: 30
res is: 50

プロトコル構成

Swift 4では、プロトコル構成の助けを借りて、複数のプロトコルを一度に呼び出すことができます。

構文

protocol<SomeProtocol, AnotherProtocol>

protocol stname {
   var name: String { get }
}
protocol stage {
   var age: Int { get }
}
struct Person: stname, stage {
   var name: String
   var age: Int
}
func print(celebrator: stname & stage) {
   print("\(celebrator.name) is \(celebrator.age) years old")
}
let studname = Person(name: "Priya", age: 21)
print(studname)

let stud = Person(name: "Rehan", age: 29)
print(stud)

let student = Person(name: "Roshan", age: 19)
print(student)

プレイグラウンドを使用して上記のプログラムを実行すると、次の結果が得られます-

Person(name: "Priya", age: 21)
Person(name: "Rehan", age: 29)
Person(name: "Roshan", age: 19)

プロトコル適合性の確認

プロトコルの適合性は、型キャストと同様の「is」および「as」演算子によってテストされます。

  • is演算子は、インスタンスがプロトコル標準に準拠している場合はtrueを返し、失敗した場合はfalseを返します。
  • ダウンキャスト演算子の* as?*バージョンは、プロトコルのタイプのオプション値を返します。インスタンスがそのプロトコルに準拠していない場合、この値はnilです。 *ダウンキャスト演算子のasバージョンは、ダウンキャストをプロトコルタイプに強制し、ダウンキャストが成功しない場合、ランタイムエラーをトリガーします。
import Foundation

@objc protocol rectangle {
   var area: Double { get }
}
@objc class Circle: rectangle {
   let pi = 3.1415927
   var radius: Double
   var area: Double { return pi* radius * radius }
   init(radius: Double) { self.radius = radius }
}
@objc class result: rectangle {
   var area: Double
   init(area: Double) { self.area = area }
}
class sides {
   var rectsides: Int
   init(rectsides: Int) { self.rectsides = rectsides }
}
let objects: [AnyObject] = [Circle(radius: 2.0),result(area:198),sides(rectsides: 4)]

for object in objects {
   if let objectWithArea = object as? rectangle {
      print("Area is \(objectWithArea.area)")
   } else {
      print("Rectangle area is not defined")
   }
}

プレイグラウンドを使用して上記のプログラムを実行すると、次の結果が得られます-

Area is 12.5663708
Area is 198.0
Rectangle area is not defined

Swift-ジェネリック

Swift 4言語は、柔軟で再利用可能な関数と型を記述する「汎用」機能を提供します。 ジェネリックは、重複を避けて抽象化を提供するために使用されます。 Swift 4標準ライブラリは、ジェネリックコードで構築されています。 Swift 4sの「配列」および「辞書」タイプは汎用コレクションに属します。 配列と辞書の助けを借りて、配列は「Int」値と「String」値またはその他の型を保持するように定義されています。

func exchange(a: inout Int, b: inout Int) {
   let temp = a
   a = b
   b = temp
}

var numb1 = 100
var numb2 = 200

print("Before Swapping values are: \(numb1) and \(numb2)")
exchange(a: &numb1, b: &numb2)
print("After Swapping values are: \(numb1) and \(numb2)")

プレイグラウンドを使用して上記のプログラムを実行すると、次の結果が得られます-

Before Swapping values are: 100 and 200
After Swapping values are: 200 and 100

汎用関数:型パラメーター

ジェネリック関数を使用して、「Int」や「String」などのデータ型にアクセスできます。

func exchange<T>(a: inout T, b: inout T) {
   let temp = a
   a = b
   b = temp
}
var numb1 = 100
var numb2 = 200

print("Before Swapping Int values are: \(numb1) and \(numb2)")
exchange(a: &numb1, b: &numb2)
print("After Swapping Int values are: \(numb1) and \(numb2)")

var str1 = "Generics"
var str2 = "Functions"

print("Before Swapping String values are: \(str1) and \(str2)")
exchange(a: &str1, b: &str2)
print("After Swapping String values are: \(str1) and \(str2)")

プレイグラウンドを使用して上記のプログラムを実行すると、次の結果が得られます-

Before Swapping Int values are: 100 and 200
After Swapping Int values are: 200 and 100
Before Swapping String values are: Generics and Functions
After Swapping String values are: Functions and Generics

関数exchange()は、上記のプログラムで説明されている値を交換するために使用され、<T>は型パラメーターとして使用されます。 初めて、関数exchange()が呼び出されて 'Int’値が返され、関数exchange()の2回目の呼び出しで 'String’値が返されます。 カンマで区切られた山括弧内に複数のパラメータタイプを含めることができます。

型パラメーターは、それが保持する型パラメーターの目的を知るためにユーザー定義として命名されます。 Swift 4は、<T>をジェネリック型パラメーター名として提供します。 ただし、配列や辞書などの型パラメーターは、それらが型「辞書」に属していることを識別するキー、値として指定することもできます。

struct TOS<T> {
   var items = [T]()
   mutating func push(item: T) {
      items.append(item)
   }
   mutating func pop() -> T {
      return items.removeLast()
   }
}

var tos = TOS<String>()
tos.push(item: "Swift 4")
print(tos.items)

tos.push(item: "Generics")
print(tos.items)

tos.push(item: "Type Parameters")
print(tos.items)

tos.push(item: "Naming Type Parameters")
print(tos.items)

let deletetos = tos.pop()

プレイグラウンドを使用して上記のプログラムを実行すると、次の結果が得られます-

[Swift 4]
[Swift 4, Generics]
[Swift 4, Generics, Type Parameters]
[Swift 4, Generics, Type Parameters, Naming Type Parameters]

ジェネリック型の拡張

スタックプロパティを拡張してアイテムの上部を知ることは、 'extension’キーワードに含まれています。

struct TOS<T> {
   var items = [T]()
   mutating func push(item: T) {
      items.append(item)
   }
   mutating func pop() -> T {
      return items.removeLast()
   }
}
var tos = TOS<String>()
tos.push(item: "Swift 4")
print(tos.items)

tos.push(item: "Generics")
print(tos.items)

tos.push(item: "Type Parameters")
print(tos.items)

tos.push(item: "Naming Type Parameters")
print(tos.items)

extension TOS {
   var first: T? {
      return items.isEmpty ? nil : items[items.count - 1]
   }
}
if let first = tos.first {
   print("The top item on the stack is \(first).")
}

プレイグラウンドを使用して上記のプログラムを実行すると、次の結果が得られます-

["Swift 4"]
["Swift 4", "Generics"]
["Swift 4", "Generics", "Type Parameters"]
["Swift 4", "Generics", "Type Parameters", "Naming Type Parameters"]
The top item on the stack is Naming Type Parameters.

型の制約

Swift 4言語では、「型制約」を使用して、型パラメーターが特定のクラスを継承するかどうかを指定したり、プロトコル適合規格を保証したりできます。

func exchange<T>(a: inout T, b: inout T) {
   let temp = a
   a = b
   b = temp
}
var numb1 = 100
var numb2 = 200

print("Before Swapping Int values are: \(numb1) and \(numb2)")
exchange(a: &numb1, b: &numb2)
print("After Swapping Int values are: \(numb1) and \(numb2)")

var str1 = "Generics"
var str2 = "Functions"

print("Before Swapping String values are: \(str1) and \(str2)")
exchange(a: &str1, b: &str2)
print("After Swapping String values are: \(str1) and \(str2)")

プレイグラウンドを使用して上記のプログラムを実行すると、次の結果が得られます-

Before Swapping Int values are: 100 and 200
After Swapping Int values are: 200 and 100
Before Swapping String values are: Generics and Functions
After Swapping String values are: Functions and Generics

関連するタイプ

Swift 4では、キーワード 'associatedtype’によってプロトコル定義内で関連型を宣言できます。

protocol Container {
   associatedtype ItemType
   mutating func append(item: ItemType)
   var count: Int { get }
   subscript(i: Int) -> ItemType { get }
}
struct TOS<T>: Container {
  //original Stack<T> implementation
   var items = [T]()
   mutating func push(item: T) {
      items.append(item)
   }
   mutating func pop() -> T {
      return items.removeLast()
   }

  //conformance to the Container protocol
   mutating func append(item: T) {
      self.push(item: item)
   }
   var count: Int {
      return items.count
   }
   subscript(i: Int) -> T {
      return items[i]
   }
}
var tos = TOS<String>()
tos.push(item: "Swift 4")
print(tos.items)

tos.push(item: "Generics")
print(tos.items)

tos.push(item: "Type Parameters")
print(tos.items)

tos.push(item: "Naming Type Parameters")
print(tos.items)

プレイグラウンドを使用して上記のプログラムを実行すると、次の結果が得られます-

[Swift 4]
[Swift 4, Generics]
[Swift 4, Generics, Type Parameters]
[Swift 4, Generics, Type Parameters, Naming Type Parameters]

Where句

型制約により、ユーザーは汎用関数または型に関連付けられた型パラメーターの要件を定義できます。 関連する型の要件を定義するために、「where」句は型パラメーターリストの一部として宣言されます。 'where’キーワードは、型パラメーターのリストの直後に配置され、その後に関連する型の制約、型と関連する型の間の等価関係が続きます。

protocol Container {
   associatedtype ItemType
   mutating func append(item: ItemType)
   var count: Int { get }
   subscript(i: Int) -> ItemType { get }
}
struct Stack<T>: Container {
  //original Stack<T> implementation
   var items = [T]()
   mutating func push(item: T) {
      items.append(item)
   }
   mutating func pop() -> T {
      return items.removeLast()
   }

  //conformance to the Container protocol
   mutating func append(item: T) {
      self.push(item: item)
   }
   var count: Int {
      return items.count
   }
   subscript(i: Int) -> T {
      return items[i]
   }
}
func allItemsMatch<
C1: Container, C2: Container
where C1.ItemType == C2.ItemType, C1.ItemType: Equatable>
(someContainer: C1, anotherContainer: C2) -> Bool {
  //check that both containers contain the same number of items
   if someContainer.count != anotherContainer.count {
      return false
   }

  //check each pair of items to see if they are equivalent
   for i in 0..<someContainer.count {
      if someContainer[i] != anotherContainer[i] {
         return false
      }
   }
  //all items match, so return true
   return true
}
var tos = Stack<String>()

tos.push(item: "Swift 4")
print(tos.items)

tos.push(item: "Generics")
print(tos.items)

tos.push(item: "Where Clause")
print(tos.items)

var eos = ["Swift 4", "Generics", "Where Clause"]
print(eos)

プレイグラウンドを使用して上記のプログラムを実行すると、次の結果が得られます-

[Swift 4]
[Swift 4, Generics]
[Swift 4, Generics, Where Clause]
[Swift 4, Generics, Where Clause]

Swift-アクセス制御

コードブロック、モジュール、および抽象化へのアクセスを制限するには、アクセス制御を使用します。 クラス、構造、および列挙は、アクセス制御メカニズムによって、それらのプロパティ、メソッド、初期化子、および添え字に従ってアクセスできます。 プロトコルの定数、変数、および関数は制限されており、アクセス制御を介してグローバルおよびローカルとしてアクセスできます。 プロパティ、タイプ、機能に適用されるアクセス制御は「エンティティ」と呼ばれます。

アクセス制御モデルは、モジュールとソースファイルに基づいています。

モジュールは、コード配布の単一ユニットとして定義され、キーワード「import」を使用してインポートできます。 ソースファイルは、複数のタイプと機能にアクセスするモジュール内の単一のソースコードファイルとして定義されます。

Swift 4言語では、3つの異なるアクセスレベルが提供されます。 パブリック、内部、プライベートアクセスです。

S.No Access Levels & Definition
1

Public

定義モジュールのソースファイル、定義モジュールをインポートする別のモジュールのソースファイルでエンティティを処理できるようにします。

2

Internal

定義モジュールのソースファイル内でエンティティを使用できるようにしますが、そのモジュール外のソースファイルでは使用できません。

3

Private

エンティティの使用を独自の定義ソースファイルに制限します。 プライベートアクセスは、特定のコード機能の実装の詳細を隠す役割を果たします。

構文

public class SomePublicClass {}
internal class SomeInternalClass {}
private class SomePrivateClass {}

public var somePublicVariable = 0
internal let someInternalConstant = 0
private func somePrivateFunction() {}

機能タイプのアクセス制御

一部の関数は、戻り値なしで関数内で宣言された引数を持つ場合があります。 次のプログラムは、sum()関数の引数としてaとbを宣言します。 関数自体の内部で、引数aおよびbの値は、関数呼び出しsum()を呼び出すことによって渡され、その値が出力されるため、戻り値が削除されます。 関数の戻り値の型をprivateにするには、private修飾子を使用して関数の全体的なアクセスレベルを宣言します。

private func sum(a: Int, b: Int) {
   let a = a + b
   let b = a - b
   print(a, b)
}

sum(a: 20, b: 10)
sum(a: 40, b: 10)
sum(a: 24, b: 6)

プレイグラウンドを使用して上記のプログラムを実行すると、次の結果が得られます-

30 20
50 40
30 24

列挙型のアクセス制御

public enum Student {
   case Name(String)
   case Mark(Int,Int,Int)
}
var studDetails = Student.Name("Swift 4")
var studMarks = Student.Mark(98,97,95)

switch studMarks {
   case .Name(let studName):
      print("Student name is: \(studName).")
   case .Mark(let Mark1, let Mark2, let Mark3):
      print("Student Marks are: \(Mark1),\(Mark2),\(Mark3).")

}

プレイグラウンドを使用して上記のプログラムを実行すると、次の結果が得られます-

Student Marks are: 98,97,95

Swift 4言語の列挙は、列挙の個々のケースに対して同じアクセスレベルを自動的に受け取ります。 たとえば、3つのサブジェクトで保護されている学生の名前とマークにアクセスするとします。列挙名はstudentとして宣言され、enumクラスに存在するメンバーは文字列データ型に属する名前です。 生徒の名前または採点したマークにアクセスするため。 現在、switch caseは、そのcaseブロックが実行された場合、学生名を印刷します。そうでない場合、学生によって保護されたマークを印刷します。 両方の条件が満たされない場合、デフォルトのブロックが実行されます。

サブクラスのアクセス制御

Swift 4では、ユーザーは現在のアクセスコンテキストでアクセスできるクラスをサブクラス化できます。 サブクラスは、スーパークラスよりも高いアクセスレベルを持つことはできません。 ユーザーは、内部スーパークラスのパブリックサブクラスの作成を制限されています。

public class cricket {
   internal func printIt() {
      print("Welcome to Swift 4 Super Class")
   }
}

internal class tennis: cricket {
   override internal func printIt() {
      print("Welcome to Swift 4 Sub Class")
   }
}

let cricinstance = cricket()
cricinstance.printIt()

let tennisinstance = tennis()
tennisinstance.printIt()

プレイグラウンドを使用して上記のプログラムを実行すると、次の結果が得られます-

Welcome to Swift Super Class
Welcome to Swift Sub Class

定数、変数、プロパティ、添え字のアクセス制御

Swift 4の定数、変数、またはプロパティは、その型よりもパブリックとして定義できません。 プライベートタイプでパブリックプロパティを記述することは無効です。 同様に、添え字は、そのインデックスまたは戻り値の型よりもパブリックにすることはできません。

定数、変数、プロパティ、または添え字がプライベートタイプを使用する場合、定数、変数、プロパティ、または添え字もプライベートとしてマークする必要があります-

private var privateInstance = SomePrivateClass()

ゲッターとセッター

定数、変数、プロパティ、およびサブスクリプトのゲッターとセッターは、それらが属する定数、変数、プロパティ、またはサブスクリプトと同じアクセスレベルを自動的に受け取ります。

class Samplepgm {
   var counter: Int = 0{
      willSet(newTotal) {
         print("Total Counter is: \(newTotal)")
      }
      didSet {
         if counter > oldValue {
            print("Newly Added Counter \(counter - oldValue)")
         }
      }
   }
}

let NewCounter = Samplepgm()
NewCounter.counter = 100
NewCounter.counter = 800

プレイグラウンドを使用して上記のプログラムを実行すると、次の結果が得られます-

Total Counter is: 100
Newly Added Counter 100
Total Counter is: 800
Newly Added Counter 700

初期化子とデフォルトの初期化子のアクセス制御

カスタム初期化子には、初期化するタイプ以下のアクセスレベルを割り当てることができます。 必要なイニシャライザは、所属するクラスと同じアクセスレベルを持っている必要があります。 初期化子のパラメータの型は、初期化子自身のアクセスレベルよりもプライベートにすることはできません。

initialize 'required’キーワードの各サブクラスを宣言するには、init()関数の前に定義する必要があります。

class classA {
   required init() {
      let a = 10
      print(a)
   }
}
class classB: classA {
   required init() {
      let b = 30
      print(b)
   }
}
let res = classA()
let print = classB()

プレイグラウンドを使用して上記のプログラムを実行すると、次の結果が得られます-

10
30
10

デフォルトの初期化子は、その型がパブリックとして定義されていない限り、初期化する型と同じアクセスレベルを持ちます。 デフォルトの初期化がパブリックとして定義されている場合、内部と見なされます。 ユーザーが別のモジュールの引数なしの初期化子を使用して初期化できるパブリック型を必要とする場合は、パブリック引数なしの初期化子を型の定義の一部として明示的に指定します。

プロトコルのアクセス制御

既存のプロトコルから機能を継承するために新しいプロトコルを定義する場合、互いのプロパティを継承するために、両方に同じアクセスレベルを宣言する必要があります。 Swift 4のアクセス制御では、ユーザーは「内部」プロトコルを継承する「パブリック」プロトコルを定義できません。

public protocol tcpprotocol {
   init(no1: Int)
}
public class mainClass {
   var no1: Int     //local storage
   init(no1: Int) {
      self.no1 = no1//initialization
   }
}
class subClass: mainClass, tcpprotocol {
   var no2: Int
   init(no1: Int, no2 : Int) {
      self.no2 = no2
      super.init(no1:no1)
   }

  //Requires only one parameter for convenient method
   required override convenience init(no1: Int) {
      self.init(no1:no1, no2:0)
   }
}

let res = mainClass(no1: 20)
let print = subClass(no1: 30, no2: 50)

print("res is: \(res.no1)")
print("res is: \(print.no1)")
print("res is: \(print.no2)")

プレイグラウンドを使用して上記のプログラムを実行すると、次の結果が得られます-

res is: 20
res is: 30
res is: 50

拡張機能のアクセス制御

Swift 4では、ユーザーが拡張機能を使用してプロトコル準拠を追加する場合、拡張機能に明示的なアクセスレベル修飾子を提供することはできません。 拡張内の各プロトコル要件実装のデフォルトのアクセスレベルには、独自のプロトコルアクセスレベルが用意されています。

ジェネリックのアクセス制御

ジェネリックを使用すると、ユーザーは型パラメーターの型制約にアクセスするための最小アクセスレベルを指定できます。

public struct TOS<T> {
   var items = [T]()
   mutating func push(item: T) {
      items.append(item)
   }
   mutating func pop() -> T {
      return items.removeLast()
   }
}

var tos = TOS<String>()
tos.push(item: "Swift 4")
print(tos.items)

tos.push(item: "Generics")
print(tos.items)

tos.push(item: "Type Parameters")
print(tos.items)

tos.push(item: "Naming Type Parameters")
print(tos.items)
let deletetos = tos.pop()

プレイグラウンドを使用して上記のプログラムを実行すると、次の結果が得られます-

[Swift 4]
[Swift 4, Generics]
[Swift 4, Generics, Type Parameters]
[Swift 4, Generics, Type Parameters, Naming Type Parameters]

タイプエイリアスのアクセス制御

ユーザーは、タイプエイリアスを定義して、異なるアクセス制御タイプを処理できます。 ユーザーは、同じアクセスレベルまたは異なるアクセスレベルを定義できます。 型エイリアスが「private」の場合、関連付けられているメンバーは「private、internal of public type」として宣言できます。 型エイリアスがパブリックの場合、メンバーは「内部」または「プライベート」名としてエイリアスにすることはできません

定義するすべてのタイプエイリアスは、アクセス制御の目的で特殊タイプとして扱われます。 タイプエイリアスのアクセスレベルは、エイリアスを設定するタイプのアクセスレベル以下にすることができます。 たとえば、プライベートタイプエイリアスはプライベート、内部、またはパブリックタイプをエイリアスできますが、パブリックタイプエイリアスは内部またはプライベートタイプをエイリアスできません。

public protocol Container {
   associatedtype ItemType
   mutating func append(item: ItemType)
   var count: Int { get }
   subscript(i: Int) -> ItemType { get }
}
struct Stack<T>: Container {
  //original Stack<T> implementation
   var items = [T]()
   mutating func push(item: T) {
      items.append(item)
   }
   mutating func pop() -> T {
      return items.removeLast()
   }

  //conformance to the Container protocol
   mutating func append(item: T) {
      self.push(item: item)
   }
   var count: Int {
      return items.count
   }
   subscript(i: Int) -> T {
      return items[i]
   }
}
func allItemsMatch<
   C1: Container, C2: Container
   where C1.ItemType == C2.ItemType, C1.ItemType: Equatable>
   (someContainer: C1, anotherContainer: C2) -> Bool {

  //check that both containers contain the same number of items
   if someContainer.count != anotherContainer.count {
      return false
   }

  //check each pair of items to see if they are equivalent
   for i in 0..<someContainer.count {
      if someContainer[i] != anotherContainer[i] {
         return false
      }
   }
  //all items match, so return true
   return true
}
var tos = Stack<String>()
tos.push(item: "Swift 4")
print(tos.items)

tos.push(item: "Generics")
print(tos.items)

tos.push(item: "Where Clause")
print(tos.items)

var eos = ["Swift 4", "Generics", "Where Clause"]
print(eos)

プレイグラウンドを使用して上記のプログラムを実行すると、次の結果が得られます-

[Swift 4]
[Swift 4, Generics]
[Swift 4, Generics, Where Clause]
[Swift 4, Generics, Where Clause]

迅速なエンコードとデコード

Swift 4には新しい Codable プロトコルが導入されており、特別なコードを記述することなく、値の型を失うことを心配することなく、カスタムデータ型をシリアル化および非シリアル化できます。

struct Language: Codable {
   var name: String
   var version: Int
}
let swift = Language(name: "Swift", version: 4)
let java = Language(name: "java", version: 8)
let R = Language(name: "R", version: 3

LangauageはCodable Protocolに準拠していることに注意してください。 次に、簡単な1行を使用して、Json Data Representationに変換します。

let encoder = JSONEncoder()
if let encoded = try? encoder.encode(java) {
  //Perform some operations on this value.
}

Swiftは、データ型内のすべての値を自動的にエンコードします。

次のようなデコーダー機能を使用してデータをデコードできます

let decoder = JSONDecoder()
if let decoded = try? decoder.decode(Language.self, from: encoded) {
  //Perform some operations on this value.
}

JSONEncoderとそれに対応するプロパティリストPropertyListEncoderの両方には、それらの動作をカスタマイズするための多くのオプションがあります。 Swift-compile-swift-online