Servlet/JSP基礎編05 サーブレットのリクエスト処理02

 


作成するプログラム

今回作成するプログラムは、前回と同じように、リクエスト処理の理解のためのものである。まず、HTML文書では、セレクトボックス、ラジオボタン、テキストエリア、チェックボックスを配置する。それぞれ違った入力のものだが、サーブレットのほうでは、どのようにして、これらのリクエストを受け取ることができるのかを検証していきたいと思う。

HTMLの作成

上記に示した要素を取り入れたプログラムを書いていく。

例として、ウェブショッピングの会計時の画面を参考にする。

下がプログラムである。

<!DOCTYPE html>
<html>
    <head>
    <meta charset="UTF-8">
    <title>Servlet/JSP Samples</title>
    </head>
    <body>

    <form action="select" method="post">
    <p>購入数を選択してください</p>
    <select name="count">
        <option value="1">1</option>
        <option value="2">2</option>
        <option value="3">3</option>
    </select>
    <input type="radio" name="payment" value="カード" checked>カード
    <input type="radio" name="payment" value="代金引換">代金引換
    <input type="radio" name="payment" value="銀行振込">銀行振込
    <input type="radio" name="payment" value="コンビニ">コンビニ

    <p>商品のご感想をお寄せください</p>
    <p><textarea name="review" cols="30" rows="5">商品名:</textarea></p>

    <p>お知らせメールの受信を希望されますか?</p>
    <p><input type="checkbox" name="mail">おすすめ商品のメールを受け取る</p>

    <p><input type="submit" value="確定"></p>
    </form>


    </body>
</html>

 まず、formタブでサーブレットの指定と、POSTメソッドを指定する。

次に、上から、セレクトタブで購入数。ラジオボタンで支払方法。テキストエリアに商品の感想。チェックボックスにメールの受け取りの選択。そして、最後に確定を押すと、サーブレットにリクエストが送られるようになっている。

実際の画面はこのようになっている。

 

 f:id:kouki-matsuura:20200825043129p:plain

サーブレットの作成

サーブレットでは、複数のリクエストに対応できるようなプログラムにしないといけない。しかし、難しいことはなく、一つのリクエストを受け取れるのなら、複数だって受け取れるはず。

「getParameterメソッド」で全て変数に入れましょう。

下記がそのプログラムになる。

public class Select extends HttpServlet{

    public void doPost(HttpServletRequest request , HttpServletResponse response
    throws ServletExceptionIOException{

        response.setContentType("text/html ; charset=UTF-8");
        PrintWriter out = response.getWriter();

        request.setCharacterEncoding("UTF-8");
        String count = request.getParameter("count");
        String payment = request.getParameter("payment");
        String review = request.getParameter("review");
        String mail = request.getParameter("mail");

        Page.header(out);
        out.println("<p>"+ count + "個の商品をカートを入れました。</p>");
        out.println("<p>お支払い方法を"+payment+"に設定しました。</p>" );
        out.println("<p>ご感想ありがとうございます。</p>");
        out.println("<p>「"+review+"」</p>");
        if(mail != null){
            out.println("<p>メールをお送りします。</p>");
        }else{
            out.println("<p>メールをお送りしません");
        }
        Page.footer(out);
    }
}

 前回を理解できた人なら、これもすぐに理解できるでしょう。

購入数のデータを変数countに、支払方法を変数paymentに、商品の感想の内容を変数reviewに、メールの受け取りの選択を変数mailにそれぞれ入れる。

あとは、printlnメソッドで表示する。一つポイントとして、メールの受け取りを拒否した場合は、チェックボックスにチェックが入らないので、変数mailの中には何も入りません。なので、nullの場合を想定しなければなりません。よって、if文で条件分岐をします。結果は以下の通りになります。

f:id:kouki-matsuura:20200825044132p:plain

このブラウザの選択に対してブラウザの表示は次のようになった。

 

3個の商品をカートを入れました。

お支払い方法をnullに設定しました。

ご感想ありがとうございます。

「商品名:ああああああ」

メールをお送りしません

 

プログラム通り、問題なく、表示されていることが分かると思う。

おわりに

今回は複数のリクエストに対して、サーブレットの対応を解説した。理解してほしいポイントとしては、セレクトボックスやラジオボタンなど、要素は違うが、サーブレット側では同じように扱えるということである。また、何も入力されない場合も考えて、条件分岐も挟まないといけない。

次回は、パラメータの値ではなく、デバッグの際に必要となる、パラメータ名の取得について解説したいと思う。

Servlet/JSP基礎編04 サーブレットのリクエスト処理1

作成するプログラム

前回のプログラムでは、サーブレットに慣れてもらうためにレスポンス処理のみのものを紹介した。

今回の記事では、実際のWebサイトのようにリクエストを拾い、それに対応するレスポンスをするプログラムを作成しようと思っている。

まずは、僕らが入力するHTML文書の作成をし、それに対応するサーブレットを作成する。

HTMLの作成

HTMLには、わかりやすくリクエストを送れるもののほうが良いと思うので、シンプルにテキストボックスとsubmitボタンを配置する。

下のプログラムが今回のHTML文書である。

<!DOCTYPE HTML>
<html>
    <head>
    <meta charset="UTF-8">
    <title>Servlet/JSP Samples</title>
    </head>
    <body>

        <p>お名前を入力してください</p>
        <form action="greeting" method="post">
        <input type="text" name="user">
        <input type="submit" value="確定">
        </form>
    </body>
</html>

 HTMLを知っている人なら、そんなに難しくないプログラムである。

「お名前を入力してください」という文章をのせ、その下にテキストボックスと確定ボタンを設置する。

formタグのaction属性には、送信先を指定するので、サーブレットのURLを指定する。そして、HTTPリクエストには、「GET」、「POST」の二つがあるが、今回は「POST」とする。

・GETリクエストとPOSTリクエス

GETリクエストを指定すると、送信するとき、リクエストパラメータ、今回の例でいうと、テキストボックスの内容がアドレスバーのURLに付属されてしまう。

POSTリクエストはアドレスバーに付属されない。

今回の場合は、特に他人にテキストボックスの中身が見られても問題はないが、パスワードの入力などには、POSTリクエストをするのが、無難である。

サーブレットの作成

サーブレットでは、先ほど作成したHTML文書のリクエストの中身を取り出して、

「こんにちは、〇〇さん」と表示するプログラムを作成する。

まず、リクエストを取り出す前に、レスポンスとの文字エンコーディングを一致させないと、文字化けが発生するので、「response.setContentType」と「request.setCharacterEncoding」を記述し、「UTF-8」で一致させる。

次に、リクエストを取り出す処理である。この処理ができるメソッドはいくつかあるが、最も基本的な「getParameterメソッド」を使用する。しかし、一つ注意点があり、入力値が数値であってもString型として戻り値がくるということである。そのため、今回のような名前を表示するプログラムでは問題ないが、数値として扱いたいときは、String型からInt型などにキャストをする必要がある。

では、実際に書いたプログラムを載せたいと思う。

@WebServlet(urlPatterns={"/chapter5/greeting"})
public class Greeting extends HttpServlet{

    public void doPost(HttpServletRequest request,HttpServletResponse response

 

 



    throws ServletExceptionIOException{

        response.setContentType("text/html; charset=UTF-8");
        PrintWriter out = response.getWriter();

        request.setCharacterEncoding("UTF-8");
        String user = request.getParameter("user");

        Page.header(out);
        out.println("<p>こんにちは、"+ user +"さん</p>");
        Page.footer(out);
    }
}

 Webアノテーションでは、「greeting」と指定しており、先ほどのHTMLのformタグのaction属性でも「greeting」と指定しているので、個のサーブレットに処理が任されることになる。

リクエストをString型の変数userに入れている。そして、「getParameter」の引数には、HTML文書の方のname属性の名前を入力すると、その属性の変数が手に入る。

変数に格納できれば、通常のJavaプログラムの変数と同じ扱いをしてもよい。

実行した結果は以下のようになった。

f:id:kouki-matsuura:20200825021502p:plainf:id:kouki-matsuura:20200825021505p:plain

まずは、入力欄に、自分の名前を入れ、確定のボタンを押す。

 

こんにちは、koukiさん

 

問題なく表示されている。

おわりに

最もシンプルなリクエストとレスポンスを扱った。これで、リクエストがどのようなものか少しはわかっていただけたかと思う。

次回の記事では、もう少し、本格的なHTMLを作成し、リクエストとレスポンスの理解を深めたいと思う。

Servlet/JSP基礎編03 WEB.xmlとサーブレット

web.xmlを使用する

web.xmlとは、Webアプリケーションの動作設定を行うファイルである。

サーブレットのURLや初期化パラメータを記述できたり、フィルタの各種設定などが可能となっている。サーブレットのURLは前の記事で紹介したWebServletアノテーションと同じものである。

小さなアプリケーションであるなら、WebServletアノテーションが楽であるが、しかし、逆にたくさんのサーブレットを持つ場合はweb.xmlを使用して管理したほうが楽である。

今回のプログラムに使用するweb.xmlを実際に作成した。

<?xml version="1.0" encoding="UTF-8"?>
    xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee
        version="3.1">

    <servlet-name>hello3</servlet-name>
    <servlet-class>chapter4.Hello3</servlet-class>

<servlet-mapping>
    <servlet-name>hello3</servlet-name>
    <url-pattern>/chapter4/hello3</url-pattern>
</servlet-mapping>

 このweb.xmlの上半分はどのxmlでも共通する部分のため、特に解説しない。

重要になってくるのは、<servlet>と<servlet-mapping>で囲まれている部分である。

<servlet-name>はサーブレットを指定するための名前である。

<servlet-class>は作成するプログラムのクラスを記述する場所で「パッケージ名・クラス名」で指定する。

<url-pattern>はWebServletアノテーションと同じものを記述すればよい。

Hello3.javaプログラム

このプログラムでは、サーブレットの特徴である、Javaプログラムの中にHTMLを記述していきたいと思う。

ブラウザに「hello」「こんにちは」と日時を表示するプログラムとする。

このプログラムは」3つのファイルから構成する。理由として、今後もサーブレットを作るうえで、共通する部分を毎回記述するよりは、共通部分だけを別のファイルとして作成しておけば、次回からはインポートするだけで1行で何行分も表現できる。

なので、「Page」クラスを作成した。このクラスでは、headerメソッドと、footerメソッドを記述している。内容は以下のとおりである。

package tool;

import java.io.PrintWriter;

public class Page{

    public static void header(PrintWriter out){
        out.println("<!DOCTYPE html>");
        out.println("<html>");
        out.println("<head>");
        out.println("<meta charset='UTF-8'>");
        out.println("<title>Servlet/JSP Sample Programs</title>");
        out.println("</head>");
        out.println("<body>");
    }

    public static void footer(PrintWriter out){
        out.println("</body>");
        out.println("</html>");
    }
}

 特に難しいことは記述しておらず、HTMLを書いたことがある方なら見たことがあると思う。この部分はどのHTML文書でも記述しないといけないので、このように一つにまとめておけば、かなり楽になる。

では、Hello3プログラムを載せる。

public class Hello3 extends HttpServlet{

    public void doGet(HttpServletRequest request , HttpServletResponse response)
     throws ServletExceptionIOException{
        
        response.setContentType("text/html; charset=UTF-8");
        PrintWriter out = response.getWriter();
  
        Page.header(out);
        out.println("<p>Hello!</p>");
        out.println("<p>こんにちは</p>");
        out.println("<p>"new java.util.Date() +"</p>");

       Page.footer(out);
    }
}

 doGetメソッドの中身を見てほしい。

setContentTypeで、レスポンスのMIMEタイプやエンコーディングを指定している。前の記事のプログラムでは、MIMEが「plain」となっていたが、今回はHTMLとして、渡すので、「html」と書いた。

そして、最も重要となるのは、Page.headerからである。共通部分はPageクラスに記述しているので、このような形で小さくまとめることができる。

あとは、printlnメソッドの中に<p>タグで、表示したい内容を書き込めばよい。

実際にコンパイルして、表示された内容が以下である。

 

Hello!

こんにちは

Mon Aug 24 05:36:42 JST 2020

 

問題なく、HTML文書として処理されているので、<p>タグはブラウザに表示されていないことが分かる。

おわりに

今回は、web.xmlについての説明と、HTMLをレスポンスとするサーブレットの作成を実際にした。

次回は、レスポンスだけでなく、サーブレットのリクエストの処理について触れていきたいと思う。

Servlet/JSP基礎編02

開発環境

テキストエディタ

文字のエンコーディングUTF-8を指定できるものを選択する。有名なものでは「ATOM」があるが、僕は日常的によく利用する「Visual Studio Code」を使う。

アプリケーションサーバ

前の記事でも紹介した通り、「Tomcat」を使う。アプリケーションサーバサーブレットJSPを使ったWEBアプリケーションを実行するために必要となる。

・データベース

データベース管理システムには「H2」を用いる。理由として、Javaとの相性がとても良いという点がある。

サーブレットプログラムの作成

最初のプログラムでは、シンプルにブラウザに「helloservlet」と表示し、横に日時などを表示するものを書く。

f:id:kouki-matsuura:20200823042833p:plain

プログラムの解説をすると、

まず、9行目では、WebServletアノテーションを記述している。URLパターンを指定している。指定するルールとしては、コンテキストルートから記述することである。コンテキストルートとはWebアプリケーションの最上位のパスのことである。

次に、helloクラスの定義をしている。また、このクラスは、「javax.servlet.http.HttpServletクラス」のサブクラスとして定義する。

12行目では、HttpServletクラスを継承しているため「doGetメソッド」を使用できる。

このメソッドの引数には、コンテナからくるリクエストと逆に返すレスポンスが入っている。

メソッドの中身では、リクエストを解釈し、レスポンスを生成する処理が一般に書かれるが、今回は特にリクエストがないため、レスポンスだけを返す形となる。

レスポンスを出力するためには、Print Writerオブジェクトが必要となるため、宣言をし、変数に代入する。そして、その変数を利用して、ブラウザに表示したい文章などをprintlnメソッドで書いていく。

結果は下の写真のようになった。

f:id:kouki-matsuura:20200823045306p:plain

しっかりと「helloservlet」と日時が表示されているのが分かる。

 

・疑問

僕はこのプログラムを書いたとき、1つだけ疑問が浮かんだ。サーブレットとはJavaプログラムの中にHTMLを埋め込む形のものだと思っていたが、今回のプログラムでは全く、HTMLを使用していないからである。

これの解答としては、文字エンコーディングの指定がある。これは、レスポンスのMIMEタイプの指定と、文字エンコーディングの指定ができる。

プログラム上では「response.setContentType("text/html; charset=UTF-8");」のように記述をする。このように書くと、HTML形式のレスポンスで文字エンコーディングは「UTF-8」と指定される。

今回のプログラムでは特に指定しなかったため自動的にMIMEタイプがテキストになっていた。だから、あのような結果で表示されたと考えられる。

さいごに

この記事では、最も初歩的なサーブレットのプログラムを紹介した。

次回は、サーブレットでweb.xml、HTMLを出力する処理を記述していこうと思う。

Servlet/JSP基礎編01

1.はじめに

今回はServlet/JSPについてまとめていこうと思う。

僕がServlet/JSPを学ぼうと思ったきっかけとして、Webアプリケーションの基礎を学んでみたいという思いと、使える言語の中にJavaがあったからである。

学んでいくと、かなり面白い技術だったので、かなりの数に分けて、紹介していこうと考えている。今回の記事では、「Servlet/JSPとは」について書いていく。

2.Servlet/JSPとは

2.1WEBの基礎

まず、僕たちは日常的にWebを使っている。Webサイトというのは、複数のWebページから構成されており、Webページを作成するには、この記事でも使っているHTMLを使う。

次に、WebブラウザとWebサーバについて解説する。Webブラウザとは、ネットワークを通じて得たWebページを、画面に表示するものである。分かりやすい例として、「Safari」などがある。Webサーバは、Webページのデータを管理している。分かりやすい例としては「Nginx」などがある。

このブラウザとサーバには関係があり、ブラウザ側、つまり、僕たち、閲覧者の方を、クライアントサイドといい、サーバ側をサーバサイドという。

f:id:kouki-matsuura:20200822041526p:plain

上図が二つの関係を示したものである。「HTTP Request」「HTTP Response」という言葉があるが、これを紹介していく。

2.2リクエストとレスポンス

リクエスとは、WEBサーバにデータを要求すること。

レスポンスとは、WEBサーバからの返答のことである。

「HTTP Request」は、リクエストのこと、「HTTP Response」はレスポンスのことである。

「HTTP」とは、TCPを使い、WEBにおけるデータの転送を行う通信プロトコルである。

 

2.3サーブレットアプリケーションサーバ

サーブレットJSPは、JavaEEに従ってプログラムを記述する。実行には、サーバに加え、Webコンテナが必要である。

ブラウザがサーブレットのURLを開くと、サーバとコンテナを呼ぶ。コンテナはサーブレットのクラスファイルを読み込み、実行する。

これらのサーバや、コンテナの機能を持つのが、JavaEEアプリケーションサーバである。

文章で仕組みを説明をしても分かりにくいので、図で説明する。

f:id:kouki-matsuura:20200822044815p:plain

ユーザから受けたリクエストをWebサーバが受け取り、コンテナを介して、サーブレットに渡される。サーブレットはリクエストの内容を解析し、レスポンスとして、適切なファイルを結果として返す。最後にWebサーバに結果が渡り、ユーザに返される。

これからの記事では、実際にプログラムなどを載せて、理解を深める。

プログラムなどを書いて、実行結果を得るには先ほど紹介したアプリケーションサーバが必要となる。なので、僕は「Tomcat」を利用する。

また、Javaのエディションは、普段使っているJava SEではなく、システム設計に特化したJava EEを使用する。

 

2.4JSPとは

JSPとは、JavaServerPagesの略である。

サーブレットとの違いはプログラムの記法にある。

サーブレットJavaプログラムの中にHTMLを書き込む。

JSPはHTMLの中にJavaプログラムを書き込む。

つまり、作成しようとするプログラムにHTMLの量で二つを使い分ける。HTMLの量が多い場合にはJSPとして書いたほうが良いということである。

 

2.5JSPで実行

JSPでの実行は、まず、ユーザがブラウザでJSPファイルのURLを開き、サーブレットのときと同じように、Webサーバ、Webコンテナを介して、リクエストを貰い、リクエストを解析する。次に、このファイルをサーブレットコンパイルし、実行結果として返している。

これを読んだ時の僕の感想としては、サーブレットという機能があり、HTMLに柔軟に対応できるJSPというオプションがあるというイメージである。

3.おわりに

今回は、Servlet/JSPについて、基礎的なことを説明した。

僕たちが普段、見ているサイトの裏では、このようなシステムが動いているということが少しは理解できたと思っている。

次の記事では、開発環境の紹介と、Servletの基本について書いていこうと思う。

「正規表現」について

正規表現とは

僕は最近、この「正規表現」という言葉を初めて知った。何も知らなかったため、プログラムを全く書けなかった。流石に悔しかったので、今回は正規表現に調べ、実際にプログラムも書いてみた。

正規表現とは、ある特定の文字列が、指定された規則に従っているかの判断をするものだと僕は考えた。

例えば、「abcdefg」という文字列には、「全てが半角英字」、「aで始まる」、「gで終わる」など、様々な規則に従っていることが分かる。プログラムでは、規則を指定し、その規則に合う文字列なら、ある処理を、合わないなら、別の処理をする、というものである。

利用される場面としては、メールアドレスやURLなど、特定の規則に従うものが多い。

プログラムを書いてみる

まず、メールアドレスとURLを例に挙げて、プログラムを書いてみる。

メールアドレスならば、「example@example.com

URLならば、「https://www.example.co.jp/」などがある。

メールアドレスには、最初にランダムな半角英数字が並び、「@」があり、再び、半角英数字が並ぶ。URLには、大体は初めに「http://」、「https://」などの特定の文字列が並び、半角英数字、そして、区切りのスラッシュで構成される。

大方の規則はわかったため、プログラムで書いていこうと思う。今回は「Java」で書いていく。

f:id:kouki-matsuura:20200811030510p:plain

上図は、メールアドレスが適切な形であるかを判定するプログラムである。まず、メールアドレスのルールとしては、「@」よりも前の部分では、様々な記号を利用することができる。しかし、「.」を2つ以上連続してつけることはできない。例外として、「"」で囲めば、2連続以上使用しても問題ないとされている。

このルールを適用した正規表現のパターンを作成する。

まずは、初めに今回、使用する3つのアドレスを宣言している。

次に変数pに、肝となるパターンを書き込んでいく。

初めて見る人には、暗号のようにしか見えないだろう。実際、僕もそうだった。

先頭にある「^(・・・)」はアドレスの最初の形は「・・・」でないといけないという意味である。カッコの中を見ていこう。

([0-9a-zA-Z!#$%&'*+-/=?^_`{}|~]+(.[0-9a-zA-Z!#$%&'*+-/=?^_`{}|~]+)+)

と、書かれている。[0-9]は0から9までという意味である。同様に、a-z,A-Zもaからzの小文字と大文字の意味である。後ろの記号の羅列はシンプルにそのままの記号で捉えてよい。「」で囲まれているところは文字の集まりだと考えてくれれば分かりやすいと思う。このカッコ内にある文字のどれかとマッチすれば「true」となる。「+」は算術演算子ではなく、+の前にある表現を1回以上使うということである。つまり、「で囲まれている記号を1回以上使うこと」である。

次に+から後ろにある、「()」の中身を見ていこう。このカッコは先ほどのものとは違い、「グループ」と捉えてほしい。今回の場合ならば、「.」の後ろには必ず「[0-9a-zA-Z!#$%&'*+-/=?^_`{}|~]+」でなければならないということである。

少し、難しく混乱している人もいると思うが、ずっと見ていると意味がわかるようになると思う。僕も初め見たときは暗号にしか見えなかった。

(\"[^\"]*\"))

「"」がすごく目立っていて、どのような意味かわからない人もいると思う。これは、アドレスのルールで「@」の前の部分では、「"」で囲ってさえいれば、特にルールはないので、「"」があるかどうかが重要になってくる。プログラムではこのマークはコメントなどに使われるため、通常の書き方では、「"」は文字としては扱われない。そのため、「\」を使うことで文字として扱うことができる。これをエスケープ処理という。次に「[^\"]」と書いているが、これは、「"」以外を意味している。よって、「"」で囲み、中には、「"」以外の文字が入っていれば、「true」で返される。

「@」以降は、ほとんど同じなので、説明は割愛する。

これを実行してみると、

example@gmail.com = true
..@gmail.com = false
"example..example"@gmail.com = true

となった。

example@gmail.comは最もシンプルな形である。特にルールに無視したような書き方でないため、trueとなった。

..@gmail.comは、「.」を連続して使えないというルールを無視しているため、falseとなる。

"example..example"@gmail.comは、「"」で囲っているため、「.」が連続していても、問題ないということである。

 

次は、URLの正規表現のプログラムを書いていく。

String str1 = "http://www.example.com/";

        String str2 = "https://www.example.com/";

        String str3 = "example://www.example.com/";

 

        // 正規表現のパターンを作成

        Pattern p = Pattern.compile("^https?://[a-z.:/+-?=&;%~]+$");

上図のプログラムは1つ目を少し、変更しただけである。

適当なURLを3つ並べた。

今回のパターンは先ほどのものと比べ、とてもシンプルになった。URLには、あまりルールがないためである。

先頭は「http」 、「https」のどちらかでないといけないので、「s」の後に「?」をつけることで2パターンに対応できるようにした。あとは「://」の後ろに自由に文字列を並べられるようにした。

結果は下記のようになった。

http://www.example.com/ = true
https://www.example.com/ = true
example://www.example.com/ = false

3つ目は「http」などを用いないため、falseとなっている。これはとても分かりやすいと思う。

以上が今回の例題である。

終わりに

今回は「正規表現」についてわかる範囲でまとめてみた。この記事を書きながらも様々な学びを得ることができたと感じる。

正規表現には、まだまだ色々とルールがあるが、今回の例題でよく使われる部分は補えたと思う。

Swift 「!」と「?」について

初めに

 swift を始めた頃、「?」や「!」という記号が登場している場面はよくありましたが、気にしなくても、swift自身が勝手に直してくれるので、無視していました。しかし、今後、学びを進める上で、かなり重要な部分になるのではないかと思い、ここに調べたことを残していきたいと思います。

「?」「!」とは?

これはオプショナル型と言われる型の一つだそうです。宣言の時は次のようにできます。

f:id:kouki-matsuura:20200606001944p:plain

変数aでオプショナルInt型といいます。これをすれば何がいいのか、と言うと、nilという特別な値が扱うことができます。普通の型ではこの値を扱うことができません。まずは、nilを持っていることを確かめるために次のようにaの中身を表示しました。

f:id:kouki-matsuura:20200606004236p:plain f:id:kouki-matsuura:20200606004249p:plain

では、次にオプショナルInt型の値をInt型の値と組み合わせてみます。

f:id:kouki-matsuura:20200606005103p:plain

bにa+1の値を代入すると、エラーが起こりました。エラーの内容はオプショナルInt型をInt型にするためにアンラップをしてくださいというものでした。

f:id:kouki-matsuura:20200606005124p:plain

アンラップというのはオプショナル型の変数に「!」をつけることです。つまり、「!」をつけることでオプショナル型を普通の型として扱えるということです。

「!」をつけてもう一度計算してみます。

f:id:kouki-matsuura:20200606005714p:plain

エラーが消えました!

「?」でnilを扱え、「!」で普通の型に戻すことができるということがわかりました。

オプショナル型の利点

「?」と「!」がどういうものかの基礎はわかったのですが、いまいち、「?」が何のために存在しているのか分からなくなりました。nilのようなものを使わなくても、Javaなどで使われているnullを使えば、普通の型だけでプログラムが書けると思ったのです。

疑問がどんどん浮かんできたので、調べてきました。

調べた結果、オプショナル型という制約がつくおかげでアプリケーションでのエラーが起きることを防ぐことができます。

nilはnullと同じように、アプリケーション内で参照してしまうと、落ちてしまいます。

しかし、nilはnullと違い、オプショナル型の変数でしか扱えません。しっかりとしたルールがあるため、nilかどうかチェックを省くことができます。

アプリケーションでのエラーを未然に防ぐことができることが最大の利点と言えるのかもしれません。

guard文

先ほどはオプショナル型の利点を紹介しましたが、絶対に大丈夫ということはありません。想定外の状況が発生しうることもあります。

ここでいう想定外の状況というのが、アプリケーションが落ちてしまう原因の一つの「nilの参照」です。このような状況を回避するための構文としてguard文があります。

ここでは、まず僕が作った簡単なプログラムと実行結果を貼らせていただきます。

f:id:kouki-matsuura:20200606011835p:plain f:id:kouki-matsuura:20200606011913p:plain

guard文の書き方として、”guard 条件 else { 処理A }”となってます。

条件を成立しない時に処理Aを行われることになっています。なので、配列nums[5]を参照された時に「nilです」と表示されるわけです。これで少なくとも、突然、アプリケーションが落ちるということは回避されます。

nil合体演算子

これも、nilによる、アプリケーションが落ちる現象を少し防げる工夫が施されているものです。具体的に説明すると、ある値がnilだった時に、別に指定しておいた値を代わりに処理に用いるというものです。

プログラムを作ってみました。先ほどと同じnums配列をfor文で回し、1つ1つ、関数exampleに入れています。exampleでは、引数であるnumがnilだった場合、999をansに入れ、通常の数の場合はそのまま入れるようにしました。実行結果は右下になります。普通の数である0~4は正しく表示されており、nilだったはずの要素が999になっていることが確認できました。

nil合体演算子がどういうものか理解できたと思います。

f:id:kouki-matsuura:20200609050050p:plain f:id:kouki-matsuura:20200609050107p:plain

有値オプショナル型

通常のオプショナル型では、nilが入っている可能性もあるため、guard文やnil合体演算子で処理する必要があったが、有値オプショナル型はそれらの処理を施さずに、変数に入れることができます。また、有値オプショナル型は宣言の際に「!」をつけることで宣言できます。

有値オプショナル型がよく用いられるのはUI部品だと思います。画面の上に置いたUIとプログラムをつなげた時に自動で宣言されるものも有値オプショナル型です。

f:id:kouki-matsuura:20200610060128p:plain

これが自動的にされることにより、僕たちは毎回、UIごとにnilか否かの判断をする必要がなくなります。UI部品は全て初めはnilが代入されていますが、アプリケーションを立ち上げると同時に値が勝手に格納されているので心配することもありません。とても便利なものです!

終わりに

どうだったでしょうか。今までモヤモヤしていたものが少しは晴れたような気がします。オプショナル型とは、swiftを触っている限り、ついてくるものなので今の間に学べてよかったと感じています。

次の記事では、新たなアプリを作成していこうかなと考えています。

見ていただきありがとうございました!