Hero Image
netパッケージで非推奨のTemporaryメソッドの扱いについて

はじめに こちらはKyash Advent Calendar 2022 の 13 日目の記事です。 今年の 11 月に Kyash に入社しました!サーバサイドチームのueharaです👋 今回はnet/httpパッケージの非推奨メソッドであるTemporary()について、社のメンバーから知見を共有してもらったのでその話をします。 net/http パッケージの 非推奨メソッド Temporary() について Temporary()については、フューチャー社の記事にわかりやすくまとめられています。 https://future-architect.github.io/articles/20220203a/ 上記の記事を踏まえて、ここでは非推奨になった経緯と対応について言及しようと思います。 サッと概要を話すと、Temporary()はnet.Errorインターフェースに定義されているメソッドで、一時的なエラーかどうか判定するために用意されています。 ただし、「一時的」というのがうまく定義されていないとの理由で、こちらのメソッドは Go1.18 で非推奨になりました。 net.Error.Temporary has been deprecated. https://tip.golang.org/doc/go1.18 Temporary()が非推奨になった経緯 前提として、net.Errorインターフェースは、以下のように定義されています ※ソースは Go 1.19 です // An Error represents a network error. type Error interface { error Timeout() bool // Is the error a timeout? // Deprecated: Temporary errors are not well-defined. // Most "temporary" errors are timeouts, and the few exceptions are surprising.

Hero Image
Futureパターンが使われているOSSを見てみた

はじめに @uh-zzです! この記事は、Go Advent Calendar 2022の 10 日目の記事になります! 今年は、個人的に色々なことに挑戦した年だったなあと振り返るとともに、去年のアドベントカレンダーからもう1年経つのか〜という気持ちです この記事では、Go における Future パターンをご紹介できればと思います Future パターンとは あるメソッドを呼び出すとします。 もしもオブジェクトが、そのメソッドを実行できる状態なら、実行します。 でも、実行できない状態なら、将来実行できる状態になるまで待つようにしたいとします。 その時に使えるのがこの Future パターンです。 future は「未来」という意味です もう少し正確にお話しましょう。 単にあるクラスに 「実行できる状態になるまで待つ」 という機能を入れるわけではありません。 すでに存在しているクラスに一皮かぶせて、 「実行できる状態になるまで待てるような機能を追加する」 というのが Future パターンです。 出典: 結城浩, Future パターン, デザインパターン紹介 上記の参考記事内では、Java をつかったマルチスレッドプログラミングで Future パターンが実装されています。 引用箇所の説明がほぼすべてですが、イメージ図で補足するとこんな感じになります flowchart LR 呼び出し元 --> Futureメソッド -- 実行できるようになるまで待つ --> 処理するメソッド 呼び出し元と処理するメソッドの間に Future メソッドを挟むことで、Future メソッドがプロキシ的に働き、非同期的に処理するメソッドを実行できるようになっています。 Go だとこんなかんじにかけるらしい 以下の記事で Future/Promiseという説明書されています https://ascii.jp/elem/000/001/486/1486902/ package main func readFile(path string) chan string { // ファイルを読み込み、その結果を返すFutureを返す promise := make(chan string) // readFile とは別のゴルーチンでファイルを読み出す go func() { content, err := os.

Hero Image
球面三角法による2点間の距離計算をGoで実装してみた

はじめに バックエンドエンジニアのロードマップに沿ってエンジニアとしての自己肯定感を養うシリーズです。 地球上の2点間の距離計算ってアプリだと Google Map API を使えば完了!だと思いますが、どう計算してるかって気になりますよね? 今回は球面三角法を利用した地球上の2点間の距離計算を Go で実装します。(調べたらフツーにあるんですが) 球面三角法とは その名の通り、三角関数を利用して球面上の辺や角の大きさを導出するものです。平面と球面とでの違いは辺の大きさが 球面では中心角によって表されることにあります。 よって、球面三角法を使用して算出した弧の長さ(中心角)と赤道の半径を乗算すると距離が求まります。 球面三角法の証明については、球面三角形の定理を参考にしました! (“高校生に向けて"とある通り、非常にわかりやすかったです) 球面三角法の余弦定理を利用して実際に距離を算出する方法は球面三角法の余弦定理がわかりやすいです。 実装 実装したソースコードは Github でも確認できます。 球面三角法を利用した2点間の距離計算 package main import "math" // Coordinate 緯度経度 type Coordinate struct { Longitude float64 Latitude float64 } // EarthRadius 赤道半径 const EarthRadius = 6378140 // DistanceOnTheEarth 地球上の 2 点間の距離を出す(球面三角法) func DistanceOnTheEarth(from, to Coordinate) float64 { fromLadLon := from.Longitude * math.Pi / 180 fromLadLat := from.Latitude * math.Pi / 180 toLadLon := to.

Hero Image
ソートアルゴリズムをGoで実装してみた

はじめに バックエンドエンジニアのロードマップに沿ってエンジニアとしての自己肯定感を養うシリーズです。 マージソート マージソートは、ソートのアルゴリズムで、既に整列してある複数個の列を 1 個の列にマージする際に、小さいものから先に新しい列に並べれば、新しい列も整列されている、というボトムアップの分割統治法による。大きい列を多数の列に分割し、そのそれぞれをマージする作業は並列化できる。 出典:wikipedia「マージソート」より引用 最悪の計算量が O(n log n) であるから少なくとも O(n^2)よりは速いんだろうなという印象(雑すぎるか) 以下「ソートを極める! 〜 なぜソートを学ぶのか 〜」を元に実装してみた(なるべくソースを見ないで実装を試みたがマージする箇所は折れた、、) package main import ( "fmt" "time" "github.com/uh-zz/traning/algorithm/shuffle" ) func main() { // ランダムな要素 n 個のスライス取得 input := shuffle.RandomIntList(n) inputLength := len(input) // マージソート MergeSort(&input, 0, inputLength) } // MergeSort マージソート func MergeSort(input \*[]int, left, right int) { // 要素数1つの場合は抜ける if right-left == 1 { return } // 配列を2つに分けるインデックス middle := left + (right-left)/2 // 配列左側 MergeSort(input, left, middle) // 配列右側 MergeSort(input, middle, right) var buffer []int // 左側と右側をバッファにためる(右側反転) for index := left; index < middle; index++ { buffer = append(buffer, (*input)[index]) } for index := right - 1; index >= middle; index-- { buffer = append(buffer, (*input)[index]) } // マージする scopeLeft := 0 scopeRight := len(buffer) - 1 for index := left; index < right; index++ { if buffer[scopeLeft] <= buffer[scopeRight] { // 左側採用 (*input)[index] = buffer[scopeLeft] scopeLeft++ } else { // 右側採用 (*input)[index] = buffer[scopeRight] scopeRight-- } } } これ考えたのぶっ飛んでるなあと思って Wikipedia 見てたら、考案者がフォン・ノイマンでやっぱりぶっ飛んでた(凄すぎ)