PHP（動的型付け）・PHP（動的型付け+型指定）・Go（静的型付け）の比較

型に注目してPHPとGoを比較してみます。

1年ほど前まではPHPで型を指定せずに実装していたので、その視点からまとめてみました。

## 動的型付け（PHP）の主なメリットデメリット

### メリット

少ない工数で実装が可能。型を指定しなくて良いため、コード量が少なくなる、及び型について考える必要がない。経験の少ないエンジニアでも容易に実装可能。

### デメリット

型の指定がないため、実装時に型の違いに気づけず、予期せぬバグが発生しやすい。また、型がバグの原因である場合に原因の追求に時間がかかる。

型の指定がないことで、メソッドの引数を見た際にどのような内容や意図の引数なのか分かりにくい。毎回、元のデータを追っていくのが手間となる。

例1）記事詳細情報取得
```
class ArticleService
{
    /**
     * 記事詳細情報取得
     */
    public function detail($id)
    {
        return [$article, $dramaList, $related]
        ...
    }
}
```

## 静的型付け（Go）の主なメリットデメリット

### メリット

バグを減らせる。型を指定するため、実装時に指定した型以外の場合は静的解析により、エラーを検知可能。

メソッドの引数や返り値が型指定されていことで、引数やメソッドの内容や意図が分かりやすい。

例2）記事詳細情報取得

```
package service

...

// 記事詳細情報取得
func (s *ArticleService) Detail(id int) (*view.ArticleDetailView, error) {
    ...
}

package view

...

type ArticleDetailView struct {
    ID        int                 `json:"id"`
    Title     string              `json:"title"`
    Body      string              `json:"body"`
    Published time.Time           `json:"published"`
    DramaList []*DramaListItemView `json:"drama_list"`
    Related   []*ArticleView       `json:"related"`
}

// 記事詳細のView
func NewArticleDetailView(article *model.Article, dramaList []*DramaListItemView, related []*ArticleView) *ArticleDetailView {
    return &ArticleDetailView{
        ID:        article.ID,
        Title:     article.Title,
        Body:      article.Body,
        Published: article.Published,
        DramaList: dramaList,
        Related:   related,
    }
}
```

### デメリット

型の実装経験がないと実装に時間がかかる。

## 動的型付け+型指定（PHP）

PHP7.4以降では型指定が可能となった。そのため、型指定を利用することで上記のデメリットを回避できる。

```ph
declare(strict_types=1); 
```
以下の例3は例1と比較するとどのような値が引数として必要か、返却されるのか分かりやすくなっている。また、VSコードであればArticleDetailViewにホバーすることでその詳細が表示される。

例3）記事詳細情報取得
```
class ArticleService
{
    /**
     * 記事詳細情報取得
     *
     * @param integer $id
     * @return ArticleDetailView
     */
    public function detail(int $id): ArticleDetailView
    {
        return new ArticleDetailView($article, $dramaList, $related)
        ...
    }
}

class ArticleDetailView
{
    /** @var int 記事ID */
    public int $id;
    /** @var string 記事タイトル */
    public string $title;
    /** @var string 記事Body */
    public string $body;
    /** @var string 記事作成日付 */
    public string $published;
    /** @var DramaListItemView[] 関連ドラマ */
    public array $dramaList;
    /** @var ArticleView[] 関連記事 */
    public array $related;

    public function __construct(ArticleMedia $article, array $dramaList, array $related)
    {
        ...
}
```

同時ににメリットもなくなるが、Goより、PHPの方が良いと判断できる理由には以下の3点がある。
- PHP経験者の方が多く、採用しやすい
- PHP経験者の場合、型を追加するのみであるため、学習コストが低い
- メモリの指定などがなく、他の実装ルール理解の観点でPHPの学習コストの方が低い

## テストコードを書く場合

記事をいくつか確認していると、テストコードが少なくなるといった記事もある。しかし、型の違いまで考慮してテストコードを記述しないため、PHP・Go共にテストコードの量が大きく変わるとは思わなかった。

ただし、型の指定がある場合の方が、テストデータの挿入時過不足ないデータを作成しやすい、テスト用に作成するデータの意味が分かりやすいなどの利点はあると感じました。

## 早さの観点

PHPにおいても型指定をすることで、型の観点では静的型付け同様のメリットを享受できることは分かったが、早さの観点ではGoの方が良い。

PHPのような動的型付け言語はインタプリタ言語（実行時にコンパイル）であることが多く、コンパイル言語（事前にビルドしてコンパイル）するGo（静的型付け言語）と比較した場合、実行速度が遅くなってしまう。

静的言語の方が型指定による効率的なコンパイルも実施されやすいとのこと。

## 参考にした記事
- https://qiita.com/toryuneko/items/c023031b61886cae2a99
- https://zenn.dev/garasubo/articles/typing-poem-battle
- https://kakaku-techblog.com/entry/dynamic-vs-static-typing
- https://liginc.co.jp/284306
- https://liginc.co.jp/295527