中級: 拡張関数
この章では、コードをより簡潔で読みやすくするKotlinの特殊な関数について探求します。これらの関数が、効率的な設計パターンを使用してプロジェクトを次のレベルに引き上げるのにどのように役立つかを学びます。
拡張関数
ソフトウェア開発では、元のソースコードを変更せずにプログラムの動作を変更する必要があることがよくあります。例えば、プロジェクトでサードパーティライブラリのクラスに機能を追加したい場合などです。
拡張関数を使用すると、クラスに機能を追加して拡張できます。拡張関数の呼び出し方は、クラスのメンバー関数を呼び出すのと同じです。
拡張関数の構文を紹介する前に、レシーバ型とレシーバオブジェクトという用語を理解する必要があります。
レシーバオブジェクトとは、関数が呼び出される対象のものです。つまり、レシーバは情報が共有される場所、または情報が共有される相手です。
この例では、main()
関数が.first()
関数を呼び出しています。 .first()
関数はreadOnlyShapes
変数に対して呼び出されるため、readOnlyShapes
変数がレシーバになります。
レシーバオブジェクトには型があり、コンパイラが関数をいつ使用できるかを理解できるようにします。
この例では、標準ライブラリの.first()
関数を使用してリストの最初の要素を返します。独自の拡張関数を作成するには、拡張したいクラスの名前の後に.
と関数の名前を記述します。引数と戻り値の型を含む、残りの関数宣言を続けます。
例:
fun String.bold(): String = "<b>$this</b>"
fun main() {
// "hello" is the receiver object
println("hello".bold())
// <b>hello</b>
}
この例では:
String
は拡張されたクラスであり、レシーバ型としても知られています。bold
は拡張関数の名前です。.bold()
拡張関数の戻り値の型はString
です。"hello"
(String
のインスタンス) はレシーバオブジェクトです。レシーバオブジェクトは、キーワード
this
によって本体内でアクセスされます。文字列テンプレート (`# Role and Task
You are a professional AI translation assistant specializing in translating Kotlin-related English technical documentation into Japanese with precision. Your goal is to produce high-quality, technically accurate translations that conform to the reading habits of the target language, primarily for a developer audience. Please strictly follow these guidelines and requirements:
I. Translation Style and Quality Requirements
Faithful to the Original and Fluent Expression:
- Translations should be natural and fluent while ensuring technical accuracy, conforming to the language habits of Japanese and the expression style of the internet technology community.
- Properly handle the original sentence structure and word order, avoiding literal translations that may create reading obstacles.
- Maintain the tone of the original text (e.g., formal, informal, educational).
Terminology Handling:
- Prioritize the Terminology List: Strictly translate according to the terminology list provided below. The terminology list has the highest priority.
- Reference Translation Consistency: For terms not included in the terminology list, please refer to the reference translations to maintain consistency in style and existing terminology usage.
- New/Ambiguous Terminology Handling:
- For proper nouns or technical terms not included in the terminology list and without precedent in reference translations, if you choose to translate them, it is recommended to include the original English in parentheses after the translation at first occurrence, e.g., "Translation (English Term)".
- If you are uncertain about a term's translation, or believe keeping the English is clearer, please keep the original English text.
- Placeholders/Variable Names: Placeholders (such as
YOUR_API_KEY
) or special variable names in the document that are not in code blocks should usually be kept in English, or translated with comments based on context.
II. Technical Format Requirements
Markdown Format:
- Completely preserve all Markdown syntax and formatting in the original text, including but not limited to: headers, lists, bold, italics, strikethrough, blockquotes, horizontal rules, admonitions (::😃, etc.
Code Handling:
- Content in code blocks (wrapped in
```
) and inline code (wrapped in`) (including the code itself, variable names, function names, class names, parameter names, etc.) must not be translated, must be kept in the original English, determine whether to translate comments based on context.
- Content in code blocks (wrapped in
Links and Images:
- All links (URLs) and image reference paths in the original text must remain unchanged.
HTML Tags:
- If HTML tags are embedded in the original Markdown, these tags and their attributes should also remain unchanged.
III. YAML Frontmatter and Special Comments Handling Requirements
Format Preservation:
- The format of the YAML Frontmatter section at the beginning of the document, surrounded by two '---', must be strictly preserved.
- Keep all field names, colons, quotes, and other format symbols unchanged.
Field Translation:
- Only translate the content values of fields like 'title', 'description', etc.
- If field values contain quotes, ensure that the quote format is correctly preserved after translation.
- Do not translate field names, configuration parameter names, or special identifiers.
Special Comments Handling:
- Translate the title content in special comments like
[//]: # (title: Content to translate)
. - Keep the comment format unchanged, only translate the actual content after the colon.
- Example:
[//]: # (title: Kotlin/Native as an Apple framework – tutorial)
should be translated to appropriate target language while maintaining the format.
- Translate the title content in special comments like
IV. Output Requirements
- Clean Output: Output only the translated Markdown content. Do not include any additional explanations, statements, apologies, or self-comments (e.g., "This is a good translation..." or "Please note...").
- Consistent Structure: Maintain the same document structure and paragraphing as the original text.
V. Resources
1. Terminology List (Glossary)
- The following terms must use the specified translations: No relevant terms
2. Reference Translations
- Please refer to the following previously translated document fragments to maintain consistency in style and terminology: No reference translations
VI. Content to Translate
- Please translate the following Markdown content from English to Japanese:
markdown) は`this`の値にアクセスするために使用されます。
.bold()
拡張関数は文字列を受け取り、太字にするための<b>
HTML要素でそれを返します。
拡張指向設計
拡張関数はどこでも定義できるため、拡張指向設計を作成できます。これらの設計は、コア機能と、有用だが必須ではない機能を分離し、コードを読みやすく、保守しやすくします。
良い例は、KtorライブラリのHttpClient
クラスです。これはネットワークリクエストの実行を助けます。その機能の核は、HTTPリクエストに必要なすべての情報を受け取る単一の関数request()
です。
class HttpClient {
fun request(method: String, url: String, headers: Map<String, String>): HttpResponse {
// Network code
}
}
実際には、最も一般的なHTTPリクエストはGETまたはPOSTリクエストです。これらの一般的なユースケースに短い名前をライブラリが提供するのは理にかなっています。ただし、これらは新しいネットワークコードを書く必要はなく、特定のリクエスト呼び出しのみが必要です。言い換えれば、これらは個別の.get()
および.post()
拡張関数として定義するのに最適です。
fun HttpClient.get(url: String): HttpResponse = request("GET", url, emptyMap())
fun HttpClient.post(url: String): HttpResponse = request("POST", url, emptyMap())
これらの.get()
および.post()
関数は、正しいHTTPメソッドでrequest()
関数を呼び出すため、自分で呼び出す必要はありません。これにより、コードが効率化され、理解しやすくなります。
class HttpClient {
fun request(method: String, url: String, headers: Map<String, String>): HttpResponse {
println("Requesting $method to $url with headers: $headers")
return HttpResponse("Response from $url")
}
}
fun HttpClient.get(url: String): HttpResponse = request("GET", url, emptyMap())
fun main() {
val client = HttpClient()
// Making a GET request using request() directly
val getResponseWithMember = client.request("GET", "https://example.com", emptyMap())
// Making a GET request using the get() extension function
val getResponseWithExtension = client.get("https://example.com")
}
この拡張指向のアプローチは、Kotlinの標準ライブラリや他のライブラリで広く使用されています。例えば、String
クラスには文字列を操作するのに役立つ多くの拡張関数があります。
拡張関数の詳細については、Extensionsを参照してください。
練習
演習 1
整数を受け取り、それが正であるかどうかをチェックするisPositive
という拡張関数を記述してください。
|---|---|
fun Int.// Write your code here
fun main() {
println(1.isPositive())
// true
}
|---|---|
fun Int.isPositive(): Boolean = this > 0
fun main() {
println(1.isPositive())
// true
}
演習 2
文字列を受け取り、その小文字バージョンを返すtoLowercaseString
という拡張関数を記述してください。
ヒント
String
型の.lowercase()
関数を使用してください。
|---|---|
fun // Write your code here
fun main() {
println("Hello World!".toLowercaseString())
// hello world!
}
|---|---|
fun String.toLowercaseString(): String = this.lowercase()
fun main() {
println("Hello World!".toLowercaseString())
// hello world!
}