スライスから削除する(deleteみたいな関数はない)
deleteみたいな関数はないようなので自分で書きましょう。
ダメな例
func delete(s []int, i int) []int { s = append(s[:i], s[i+1:]...) return s } func main() { s := []int{1, 2, 3, 4, 5} s = delete(s, 2) //slice:[1 2 4 5], len:4, cap:5 fmt.Printf("slice:%d, len:%d, cap:%d\n", s, len(s), cap(s)) //s == [1 2 4 5 5] fmt.Println(s[:cap(s)]) }
このままだと見た目は削除できているように見えるんですけど、容量が削除されていないため不要な値が残っているようです。
なので、容量まで削除しましょう。
良い例
func delete(s []int, i int) []int { s = append(s[:i], s[i+1:]...) //新しいスライスを用意することがポイント n := make([]int, len(s)) copy(n, s) return n } func main() { s := []int{1, 2, 3, 4, 5} s = delete(s, 2) //slice:[1 2 4 5], len:4, cap:4 fmt.Printf("slice:%d, len:%d, cap:%d\n", s, len(s), cap(s)) //s == [1 2 4 5] fmt.Println(s[:cap(s)]) }
配列に要素があるか確認する方法(containsみたいな関数はない)
containsみたいな関数はないようなので自分で書きましょう。
func contains(s []int, e int) bool { for _, v := range s { if e == v { return true } } return false }
Golangで任意の型にあたるものはinterface{}
こんにちは。がわわです。
自分が詰まった部分は「Google App EngineのDatastoreで*Keyの配列をjsonで返す」というところでした。
以下は、ヘッダーに書かれたユーザーIDのtweet一覧をTweetというカインドから引っ張ってきて、keyとtweetをjsonで返す関数を書こうと思ったダメな例です。
ダメな例
func GetTweets(w http.ResponseWriter, r *http.Request){ c := appengine.NewContext(r) q := datastore.NewQuery("Tweet"). Filter("UserId =", r.Header.Get("X-USERID")) var tweets []Tweet keys, err := q.GetAll(c, &tweets) if err != nil { panic(err) } //Keyが定義されていないからコンパイルエラー response := map[string][]*Key { "Keys": keys, "Tweets": tweets, } json, err := json.Marshal(response) if err != nil { panic(err) } w.Header().Set("Content-type", "application/json") w.Write(json) }
正しい例
//interface{}に任意の型を入れられる response := map[string]interface{}{ "Keys": keys, "Tweets": tweets, }
interface{}とはメソッドが何もない空のインターフェースということですが、任意の型を入れられるものだということがわかりました。
A Tour of Go63~72学習メモ
- goroutineは軽量なスレッド
- go funcでfuncを別スレッドで実行できる
- 同期する際はチャネルを使う
- チャネルに値を受信するまで送信されないし、受信の準備ができるまでチャネルから送信されない
- ch := make(chan 型)の形で生成
- チャネルにはバッファ(許容量)があるmakeの第二引数に設定できる
- チャネルは先入先出
- v, ok := <-c でokがtrueならチャンネルは開いてる、falseなら閉じている
- rangeなどこれ以上くる値がないことを知らせる場合は送信側のチャネルをcloseで閉じる
- selectでgoroutineをcaseの条件で一致するまでブロックし、一致したcaseを実行、複数一致ならランダム
- selectでブロックしないで送受信するならdefault文を書く
演習問題は所々飛ばしてとりあえず文法を学ぶことを優先にやってきたA Tour of Goも今日で終わり!
明日からは自分が作ってるアプリを再開して早めに終わらせたいな。
A Tour of Go55~62学習メモ
- インターフェース型のerrorにError() stringという文字列を返すメソッドが定義されている
- 返すエラーを自分で定義する際はstructを定義して、Error() stringのメソッドを実装
- httpパッケージからHTTPリクエストの処理機能が提供されている
- インターフェース型のHandlerにServeHTTP(w ResponseWriter, r *Request)というメソッドが定義されている
A Tour of Go58の解答
package main import ( "fmt" "net/http" ) type String string type Struct struct { Greeting string Punct string Who string } func (str String) ServeHTTP(w http.ResponseWriter, r *http.Request) { fmt.Fprintf(w, "%s", str) } func (str *Struct) ServeHTTP(w http.ResponseWriter, r *http.Request) { fmt.Fprintf(w, "%s%s%s", str.Greeting, str.Punct, str.Who) } func init() { http.Handle("/string", String("I'm a frayed knot.")) http.Handle("/struct", &Struct{"Hello", ":", "Gophers!"}) http.ListenAndServe("localhost:4000", nil) }
悩んだところ
- yamlファイルのscript: _go_appの部分はscriptの前にスペース2個。pythonはこういうところが厳密なので注意。
- func init()で書かなければならない。今までmain()でチュートリアルが進んでいたのでここで詰まってしまった。
- fmt.Fprintfを使わないと表示されないので注意
- http://localhost:4000/string, structでアクセスしないといけないのにhttp://localhost:4000だけでアクセスしていた
14.3項を理由にAppleにリジェクトをくらった時の解決法
こんにちは。がわわです。
iPhoneアプリには審査がありガイドラインが規定されています。
14.3
Apps that display user generated content must include a method for filtering objectionable material, a mechanism for users to flag offensive content, and the ability to block abusive users from the service
引用:App Store Review Guidelines - Apple Developer
タイトルにある14.3項とは意訳すると「ユーザーが生成したコンテンツがある場合、そのコンテンツを表示しないようにする仕組みを作らなければならない」というものです。
僕はこれでリジェクトをくらいました。
解決法は以下全て(最後のはあると望ましいです)。
Appleに伝える際はiTunesConnectのマイAppの「App Reviewに関する情報」のメモに書いておけば良いでしょう。
僕の場合はリジェクトをくらった際に問題解決センターでやりとりしている際に説明しましたけど。
なにはともあれ、1ヶ月以上かかった審査も終わりました!
"Thank you for choosing iOS and the App Store."とか言われてもめげなくて良かった!
ちなみにアプリはこれです。
ダウンロードしてくださると嬉しいです。