JSゆるふわめも

がっこうでべんきょうしたことをめもがきしてます

C#はじめます

次の業務的でC#を読む可能性が微レ存(死後)なので、基礎を勉強しようと思う。 「Javaとほとんど同じですよ!」と言われたけど、何も知らないと細かいところは分からない。

しかし、usingはJavaのtry-with resource, Goのdefer的なやつかな?とか => ってラムダなんだろうとか過去に学んできた言語の下地がある分学習効率は上がってる気がする。

JS低学年の頃はC言語でif while プリミティブ型以上!状態だったので...

Youtubeのエラーページ

数ヶ月前にYoutubeが10分ほどダウンした時にとったスクショ

A team of highly trained monkeys has been dispatched to deal with this situation.

f:id:Qlib:20171021224752p:plain

エラーメッセージ・画面もシャレが効いてる

PS4とコントローラのペアリング不調

結論から言うと電源を一度抜いたら治りました。 完全にメモリクリアする必要があったようです。

一般的な治し方?であるセーフモードを色々いじくっても全く治らなかったので途方にくれていたのですが、治って良かったです。(Amazon Primeビデオ視聴マシンと成り下がっていますが…)

ファイナライザを避ける

ファイナライザ

GCによって、インスタンスが回収されるタイミングで実行されるメソッド

ファイナライザは(原則)使用するべきでは無い

理由

  • ファイナライザは即時実行されるわけでは無い(意図しないタイミングで実行される可能性がある)
  • そもそも実行されることが保証されていない

ファイナライザ相当のことをしたい場合

  • 明示的にコールする後処理メソッドを書く
    • terminate, dipose, etc…
  • 上記メソッドがコールされたことを管理するフィールド値をオブジェクトに持たせる
    • isTerminated, isDisposed

参考: ExecutorService (Java Platform SE 6)

ファイナライザの使い所は?

上記メソッドを呼び出し忘れた時の保険

実装する場合の注意点

親クラスでファイナライザが実装されている場合、忘れずに呼び出すこと

  • かなり簡略化しているので、正確完全な情報はEffective Java原本を参照してください

text/scanner

Package scanner provides a scanner and tokenizer for UTF-8-encoded text. It takes an io.Reader providing the source, which then can be tokenized through repeated calls to the Scan function. For compatibility with existing tools, the NUL character is not allowed. If the first character in the source is a UTF-8 encoded byte order mark (BOM), it is discarded.

By default, a Scanner skips white space and Go comments and recognizes all literals as defined by the Go language specification. It may be customized to recognize only a subset of those literals and to recognize different identifier and white space characters.

スキャナパッケージはUTF-8エンコーディングされたテキストを対象にしたscannerとtokenizerを持っている。Scanメソッドを繰り返し呼び出すことで、ソースコードが記述されたio.Readerをtokenizedできる。既存のツールとの互換性を維持するために、ヌル文字は使用することができない。もしソースコードの先頭にBOMが付いていても無視される。

基本的にScannerは空白文字とコメントは読み飛ばし、Go言語仕様で定義された全てのリテラル値をパースする。しかし、scannerは異なるルールのソースコードをパースするためにカスタマイズされている場合もある。

サンプル

import (
    "fmt"
    "strings"
    "text/scanner"
)

func main() {
    const c = `
// This is scanned code.
var i int
var s string = "text"
if a > 10 {
    someParsable = text
}`
    var s scanner.Scanner
    s.Init(strings.NewReader(c))
    s.Filename = "test"
    for tok := s.Scan(); tok != scanner.EOF; tok = s.Scan() {
        fmt.Printf("%s:%v %v\n", s.Position, scanner.TokenString(tok), s.TokenText())
    }
}

実行結果

test:3:1:Ident var
test:3:5:Ident i
test:3:7:Ident int
test:4:1:Ident var
test:4:5:Ident s
test:4:7:Ident string
test:4:14:"=" =
test:4:16:String "text"
test:5:1:Ident if
test:5:4:Ident a
test:5:6:">" >
test:5:8:Int 10
test:5:11:"{" {
test:6:2:Ident someParsable
test:6:15:"=" =
test:6:17:Ident text
test:7:1:"}" }

Scanメソッドの返り値は

  • リテラル値は型
  • 変数・関数名(上記以外のもの)はIdent
  • { ( などはそのまま

scanner package

Goには良く使用するであろうbufio Scannerとは別に、構文解析を行うためのscannerパッケージに属するScanner型が存在する

Package scanner implements a scanner for Go source text. It takes a []byte as source which can then be tokenized through repeated calls to the Scan method.

scannerパッケージはGoのソースコードのscannerを実装しています。このパッケージはbyte配列をソースコードとみなし、Scanメソッドを繰り返し呼び出すことで、トークナイズします。

公式ドキュメントのScanメソッドのコード例を実行してみるとscannerパッケージの役割がよくわかる。 scanner - The Go Programming Language

 src := []byte("cos(x) + 1i*sin(x) // Euler")
1:1  IDENT   "cos"
1:4 (   ""
1:5 IDENT   "x"
1:6 )   ""
1:8 +   ""
1:10    IMAG    "1i"
1:12    *   ""
1:13    IDENT   "sin"
1:16    (   ""
1:17    IDENT   "x"
1:18    )   ""
1:20    ;   "\n"
1:20    COMMENT "// Euler"

scannerを使用して構文解析をしている例 d.hatena.ne.jp

おそらくかなり賢い32 << (^unint(0) >> 63)

プログラミング言語Go練習問題6.5で、

プラットフォームに対して最も効率的な符号無し整数を使用するために、 かなり賢い式32 << (^uint(0) >> 63) を使える。

と説明されている。 uintはプラットフォームが32bit環境なら32bitの符号無し整数・64bit環境なら64bitの符号無し整数として振る舞う。 なので、^uint(0)は32bit環境ならば0を反転しているので、32bit立った状態を表している。

したがって、(^uint(0) >> 63)は63bit文右シフトしているので、32bitならば0になり、63bitならば最下位のbitだけが立っている状態になる。

となると32 << (^uint(0) >> 63)は32bit環境ならば32 << 0で32となり、64bit環境ならば32 << 1で64となる。

なので、 おそらくかなり賢い32 << (^unint(0) >> 63) はプラットフォームのbitサイズを返す式となっている。