D言語を触ってみる
前から薄ら気になってたのでやってみる
知ってる知識
- Cの代替を目指している
- UFCS(
.
で関数を呼び出すやつ)が使える - デフォルトでGCが入っているが抜くこともできる
- ツールチェーンが揃っている
- マスコットが異常に有名
環境
- Linux(Manjaro/Hyprland)
- Vim(v9.1)
dubとかdmdとかldcとかgdcとか色々ある(名前がイマイチ覚えずらい...)
まとめると、
- dmd
公式コンパイラ - ldc
LLVMベースのコンパイラ - gdc
gccベースのコンパイラ
dubはコンパイラではなくビルドツール(cargoみたいなやつ)
なのでとりあえずdmd
とdub
をインストールすればOK
公式からシェルスクリプトのインストーラが配布されているのだけど、実行してもgpgでエラーが出てインストールできない。
mise plugins install https://github.com/sylph01/asdf-dmd.git
mise use -g dmd
dubはGitHub ReleaseにバイナリがあったのでそれをDLした。
もしReleaseに対応しているOS/Archがなくてもdmdがあればビルドすることができる。
リポジトリをgit clone
してdmd -run ./build.d
すれば./bin/
にバイナリが生成されている。手元で実行したらかなり重かったので注意
D言語はd-serve
というLSPも提供している。
エディタの拡張機能でインストールされるし、インストールに関してはあまり意識はしなさそう。
一応リポジトリをcloneしてdub build
すればバイナリが手に入る。
プロジェクトの作成はdub init
でできる。
いくつか質問されるので適当に答えていく。
自分はこんな感じで答えた。
❯ dub init
Select a package recipe format:
1) sdl 2) json
#? [2]: 2 ←Jsonの方が読みやすそう
Name [dlang-fizzbuzz]: ←ディレクトリは既に作ってあるのでスキップ
Description [A minimal D application.]: ←後から編集できるだろうし適当にスキップ。
Author name [Comamoca]: ←これで良いのでスキップ
Select or enter an SPDX license-identifier (https://spdx.org/licenses/):
1) BSL-1.0 (Boost) 8) BSD-
2) MIT 9) MPL- (Mozilla)
3) Unlicense (public domain) 10) EUPL-
4) Apache- 11) CC- (Creative Commons)
5) AGPL- 12) Zlib
6) GPL- 13) ISC
7) LGPL- 14) proprietary
? [14]: 2 ←もっぱらMITライセンスを使っているため2を選択
Copyright string [Copyright © 2024, Comamoca]:
Add dependency (leave empty to skip) []:
Success created empty project in /dlang-fizzbuzz
Package successfully created in .
これでカレントにファイルが生成されているはず。
❯ tree
.
├── dub.json
└── source
└── app.d
2 directories, 2 files
source/app.dがエントリポイントになる。
中身を見てみるとすでにプログラムが書き込まれている。
❯ cat source/app.d
import std.stdio;
void main()
{
writeln("Edit source/app.d to start your project.");
}
とりあえずこれを実行してみる
❯ dub run
# デバッグ実行である旨のメッセージが表示される
Edit source/app.d to start your project.
dubは特に引数が与えられない場合、カレントのプロジェクトをビルトして実行する。(makeっぽい挙動)
なのでrun
を付けなくても実行はされる。
❯ dub
# デバッグ実行である旨のメッセージが表示される
Edit source/app.d to start your project.
まずはおなじみのFizzbuzzを書いてみる。
matchとかmapが使えるのでRustっぽく記述できて気持ち良い。
import std.conv;
import std.range;
import std.stdio;
import std.algorithm;
void main()
{
iota(30)
.each!(n => writeln(fizzbzz(n)));
}
string fizzbzz(int n) {
switch (n % 15) {
case 0:
return "FizzBuzz";
case 3, 6, 9, 12:
return "Fizz";
case 5, 10:
return "Buzz";
default:
return to!string(n);
}
}
rangeまわりはこれを参考にした
なんとなく慣れてきた気がするので気象庁のAPiを叩いてみる。
一応Dにはcurlのバインディングが存在するけど、文字コードがらみが面倒だったのでサードパーティのdlang-requestsを使ってみる。
JSONのパースは標準のパーサーを使っている。
UFCSが使えるので型変換周りもスッキリ書けて気持ちが良い。
import requests;
import std.stdio;
import std.algorithm;
import std.array;
import std.conv;
import std.json;
void main()
{
string url = "https://www.jma.go.jp/bosai/forecast/data/forecast/130000.json";
auto resp = getContent(url);
JSONValue json = parseJSON(resp.toString);
json[0]["timeSeries"][0]["areas"][0]["weathers"]
.array
.map!(a => a.str)
.array
.join("\n")
.writeln;
}