ブックマーク / zenn.dev/nobonobo (9)

  • Goが循環インポートをエラーにする理由

    循環インポートの問題点 現代のプログラミング言語の多くは1パスでプログラムコードを解釈します。インタプリタ型は当然としてC/C++も例外ではありません。つまり「コンパイル・実行」されるまでにソースコードを2度パースすることはありません。 さらにプログラム言語の多くは多重定義はバグの元なのでエラー扱いになります。なので対策の無いヘッダーファイルをincludeした時、再度同じヘッダーファイルが参照された場合に「多重定義」になってしまいます。 C/C++ではそのような「多重定義」を回避するために「インクルードガード」という対策をヘッダーファイルに施します。C/C++ではプリプロセッサという仕掛けに依存していてコンパイラは重複する定義がそれぞれどこのファイルを読み込んだ結果かを判別できません。なので「インクルードガード」という対策がヘッダーに必要なのです。 しかし、「インクルードガード」は方針が

    Goが循環インポートをエラーにする理由
  • Goとエラーハンドリング慣習について

    エラー返値が無用な条件 関数ないしメソッドの実装がオンメモリ操作のみで完結 将来も(メモリ以外の)I/O操作は追加されることがない 逆にいうと上記の条件のいずれかが達成できない可能性がある関数やメソッドはエラー返値を付与すべき。 返値エラー型はerrorで統一する 返すエラーがerrorインターフェース型でなければそのエラーは正常にハンドリングできません。またerrorインターフェースを満たす別の返値型で返してerrorインターフェース型で受け取るのも後述のトラブルの元です。 Goの実装方針に「インターフェースで利用するものもコンストラクター相当では構造体ポインタで返す」というものがありますがコンストラクタを呼ぶ側は元型にアクセスすることが多いのでこういう方針になっています。が、エラー値に関しては元型を意識せずに利用可能にするという役割があって、この実装方針は当てはまりません。 エラーチェ

    Goとエラーハンドリング慣習について
  • GoとEnumについて

    これはGo Advent Calendar 2022の21日目の記事です。 たびたび「Enumイディオム」がGoに欲しいという要望が話題になるのでその話をまとめてみる。 議論の中心はここが詳しい。 「Enumイディオム」が解決する課題 文字列表現がつく 反復処理ができる 偽の列挙値を導入することを防ぐ 名前空間を分離する などがあるらしい。上にあげた課題がGo標準では解決しにくいという理由がよく上がるのですが、Enumイディオムの追加方法は何パターンかあります。 Enum型プリミティブを言語仕様に加える ライブラリとしてEnumオブジェクト実装を提供する 現状の推奨「iotaによる手法+go-generate」による方法 「Enum型プリミティブを言語仕様に加える」について 言語実装のアップデートが必要 reflectパッケージのアップデートが必要 後方互換のためiota式とEnum式の2

    GoとEnumについて
  • GoでクロスプラットフォームGUI(2022)

    andlabs/ui、lxn/walkは簡素なウィジェットセットだけをサポート。fyne、Qtベースは豊富なウィジェットセットを持つ。いずれも少人数でメンテしていることを考えると、コンパクトなツールキットで活発な活動中のものが品質面でおすすめです。 IMEサポートの有無は日語圏でのGUI提供において重要なファクター 英語圏生まれのGUIライブラリの多くはIMEサポートをあまり考慮していない GLFWはIMEサポートのPRが何年も取り込まれない状況がつづいている HTMLベース(ChromeやWebView)ならIMEサポートを内包している 自作系はどうしてもギョッとする挙動や細かく期待しない挙動にちょくちょく出会ってしまう(例えば日語のワードラップ未対応など) HTML系はUIを構築していく上でのほとんどのケースで細かい問題に対する解決策がちゃんとある クロス環境対応ということであれば

    GoでクロスプラットフォームGUI(2022)
  • Goとマルチコアスケール実装

    マルチコア化の未来予測 半世紀前にSF映画「2001年宇宙の旅」に登場するコンピューターHAL-9000が並列コンピューティングの未来を示しました。マルチコアで構成されたコンピューターの物理コアを取り除いてもすぐにクラッシュせずに性能ダウンして処理が継続するという演出がありました。 当時ですらシングルコアコンピューティングの限界が予想されていて、現状のコンピューティングがマルチコア化しているという未来をしっかり予測できていたことがわかります。 演出はコア数に応じてコンピューティング性能がスケールしていることを表現しています。これはマルチコアスケールするソフトウェア実装の未来を示していたと思います。 シングルコア性能向上の頭打ち 2003年以降あたりはCPUの動作周波数が伸び悩み出したところ。 https://queue.acm.org/detail.cfm?id=2181798 より その

    Goとマルチコアスケール実装
  • Go言語の記述の迷いどころについて

    この記事はGoのコードをいくらか書いていてもっとGoらしい書き方に興味を持ってからみてね!(Go初見で読んでも響かない内容です) Goは「シンプルで迷いなく書ける」というのが売りではあるのですが、 実際書き始めると、「あれ?これどうやって書くほうがいいの?」ってポイントにちょくちょく巡り合います。そのようなポイントを思い出しながら今思うベターな書き方を紹介しようと思う。 err変数束縛について err変数の受け取りを複数回繰り返していると「:=」だけで書けないという状況に出会うでしょう。 err := funcA() if err != nil { ... } err := funcB() // <- コンパイルエラー: "no new variables on left side of :=" if err != nil { ... }

    Go言語の記述の迷いどころについて
  • Goの苦手な領域

    Goの利点を使って実装するコツやノウハウを書くことがコミュニティにとってプラスになると思っているのでそれに専念したいという考えはありますが、Goの苦手な領域にGoを採用してしまってヘイトを溜め込んでしまう事例を見かけたりします。 こういう悲劇の起こる可能性を少しでも減らせたらという思いで、Goの現状の苦手な領域について解説しようと思います。Goを学び始めにこれらの領域に手を出すのは避けましょう。 Cgo is not Go GoCGO連携でC/C++資産を利用することができますが、メモリアロケータの異なる処理系を繋ぐ関係上、お互いに呼び合う際のパラメータや戻り値はほとんどのケースでコピーが必要になります(Cの型でメモリ確保しCの型のまま受け渡しする場合はOK)。なので高頻度に呼び合うような用途には不向きであるというのはSWIGなどのような複数の処理系を連携させる仕組みと同様です。 また、

    Goの苦手な領域
  • Goのプロジェクト構成の基本

    Goプロジェクトをどの様なファイル構成で配置すれば良いか読み物が少ないという指摘を見たのでまとめてみようと思う。 GOPATHについて Go1.16がリリースされたことでGo-Moduleによるプロジェクト構成が標準で推奨されることになりました。(Go1.11までさかのぼってGo-Moduleは使える様になってます) Go-Moduleモードでは「GOPATH配下にプロジェクトを置かなければならない」という制約からは解放されています。なので、実質GOPATHはどこを指していても構わないし設定されていなくても「ユーザーホーム/go」というデフォルトの場所が決まっているので開発できます。 おすすめの環境変数設定は以下の2つだけ。 「GOPATH=~/.go」(WindowsGOPATH=%USERPROFILE%\.go) 「PATH=$GOPATH/bin:$PATH」(Windows

    Goのプロジェクト構成の基本
  • Goの良さをまとめてみた

    よく知られる良さ ネイティブコード出力で実行効率が良い コードの可読性を重視している 開発でよく使うツールがバンドル クロスビルドが簡単にできる コンパイルが遅くない(LLライクにrunできる) 並行処理の抽象化を組み込み言語仕様にもつ メモリ安全である 上記の一部に解説を加えつつあまり言及されない良さを以下にまとめます。 依存解決が最小限で決定的 ここにも書きましたが、Goの依存解決は常に 最小限のダウンロード 最小の範囲でのみビルドを実行 だけが走ります。これを一度体験すると、従来のパッケージ依存管理が冗長で余計なものをビルドしすぎることに気づくでしょう。これらに相当の時間を奪われているのです。 また、Goモジュール機構によりそのバージョン選択は決定的に安定動作するバージョンに決められます。このことのメリットは数ヶ月後のリビルドで安定してビルドできることで実感できるでしょう。 開発環境

    Goの良さをまとめてみた
    digo
    digo 2020/11/11
    (自分にとっては)まず初期学習コストの低さと可読性かな。
  • 1