Closed ufcpp closed 2 years ago
メモ: Google.Protobuf が SourceLink 使ってる < F12 ステップイン可能
/*このコメントめったに使わないよね*/
#if false // こっちの方が多い
var s = """
[
{
"id": 123,
"name": "abc",
"data": [ true, null ]
},
{}
]
""";
new Regex("\\d+");
#endif
#if tru // e 1文字でコメント アウト・イン切り替え
var s = """
""";
#endif
// これやりたいけどなー
var id = 123;
var name = "abc";
var s = /*lang=json,strict*/ $$"""
{
"id": {{id}},
"name": {{name}},
"data": [ true, null ]
}
""";
// embedded language のインターフェイスが public になった暁には…
// lang 名の被り回避がいるのでは?!
var s = /*lang=jp.co.my-lang*/ """
{
"id": 123,
"name": "abc"
}
""";
ジャヴァジャヴァしてきた。
struct S
{
public int X { get; }
public int Y { get; }
public S()
{
this = default; // これ要る?
X = 1;
}
}
クラスと同様0初期化でよくない?
struct S
{
private int _x;
public int Y { get => _x; set => _x = value; }
public S()
{
Y = 1; // _x 初期化よりも前に、auto じゃないプロパティ触るな
}
}
struct S
{
public int X { get => field; set => field = value; }
public S()
{
X = 1; // じゃあ semi-auto プロパティどうするの?
// 今、これ、書けるようにする方向で検討中。
}
}
struct S
{
public int X { get; }
public int Y { get; }
public S()
{
this = default; // X に 0 → 1 で2回初期化かかる。ちょい遅。
X = 1;
}
public S()
{
X = 1;
// this = default じゃなくて Y = 0 を挿入してくれればノーコストじゃない?
}
}
struct S
{
public int X { get; }
public int Y { get; }
public S()
{
X = 1;
Console.WriteLine(Y); // 0 が出るようにするはず?
}
}
public int X
{
get => field;
set
{
field = value; // これはキーワードの field
if (true)
{
var field = 1; // どうも、OK にする模様
var value = 2; // ダメ(元からそういう仕様)
}
var a = (int field) => { }; // shadowing OK
var b = (int value) => { }; // shadowing OK
}
}
struct S
{
public int X { get => field; }
public int Y { get; }
// ↑ X と Y はほぼ同様の扱いの予定。
public S()
{
X = 1; // X のバッキングフィールドへの直代入
Y = 2; // Y のバッキングフィールドへの直代入
}
}
↑この仕様にすることにより、↓みたいになる
struct S
{
public int X { get => field; set => field = value * value; }
public S()
{
X = 2; // Q. これはどうなるの?
// (初期案の) A. バッキングフィールドへの直代入
// すなわち、new S().X は 2 になるはず。
// というのが紛らわしすぎるんで、
// ちゃんと setter 呼ぶようにしようよ見たいな話になり。
// それはそれで、「フィールド初期化後でないとプロパティを参照できない」問題にひっかかる
// なので、さっきの struct 初期化の話が出た。
}
}
struct S
{
public int X
{
get => field;
set
{
if (field != value)
{
field = value;
OnPropertyChanged("X");
}
}
}
public S()
{
X = 2;
// X の field が未初期化だと、 if(field != value) がまずい。
// ↓
// 先に0初期化する仕様が必須
}
}
また NRT ではまりそう…
var s1 = nameof(String); // OK
var s2 = nameof(string); // NG
var s3 = nameof(value); // OK
var s4 = nameof(field); // OK? NG?
ReadOnlySpan<char> s = "abc";
if (s is "abc") // 仕様として常に MemoryExtensions.SequenceEqual を使う
{
}
// 今まだ実装ないけど、↓も行けるようにするみたいな話あり
ReadOnlySpan<byte> u = "abc"u8;
if (u is "abc") // "abc"u8 扱いのはず
{
}
string s1 = "abc";
if (s1 is null) // OK
{
}
ReadOnlySpan<char> s2 = null; // これも別に OK
ReadOnlySpan<char> s = "abc";
if (s is null) // でもこれはダメな予定(暗黙の変換ダメ!)
{
}
Span<int> s = null;
Console.WriteLine(s.Length); // NO ぬるぽ。0 が返る。
// default(Span<int>) と
// (Span<int>)default(int[]) は
// 一緒であってほしい感が多少
unsafe
{
int* p = null; // null でも
for (int i = 0; i < 0; i++) // length 0 なら
{
var x = p[i]; // ぬるぽらない
}
}
Span<int> s2 = default;
unsafe
{
fixed(int* p = s2) // p は null
{
for (int i = 0; i < s2.Length; i++) // length 0 だから
{
var x = p[i]; // ぬるぽらない
}
}
}
// C# 11
var array = new[] { 1, 2, 3, 4, 5, };
if (array is [1, ..var middle, 5])
{
Console.WriteLine(string.Join(", ", middle)) ;
}
// ↓C# 11 どころかまだもうちょっと先
var list = [1, ..array, 2]; // spread operator の ..
// 1, 1,2,3,4,5, 2
Range[] rangeList = [1, ..i, 2]; // この .. は Range?それとも spread?
// とはいえ、リストリテラルの方の .. で迷いが生じるなら、
// C# 11 のリストパターンの .. にも再考の余地あり。
// 今そこが悩み。
// 今のところ、このまま .. で行くの優勢。
// ↓こんな仮想的な構文考えたときに、 .. が range か spead かマジでわからない。
// spread が ... なら問題ないんだけども…
ReadOnlySpan<byte> data1 = [0x64, 0x61, 0x74, 0x61]; // これを
ReadOnlySpan<byte> data2 = [0x64, ..0x6174, 0x61]; // こう多少書きたい気持ちがなくはない
ReadOnlySpan<byte> data3 = [..0x64617461];
// (エンディアン怖い)
ReadOnlySpan<byte> data4 = "\u0064\u0061\u0074\u0061";
ReadOnlySpan<byte> data5 = "\u64617461"; // これもダメ
ReadOnlySpan<byte> data6 = "64617461"bin; // ほんとはこんなのほしい(またC++になっちゃう…)
class A
{
[RegexGenerator(...)]
[DllImportGenerator(...)]
void M() { }
}
// RegexGenerator の生成物
class A_M { }
// DllImportGenerator の生成物
class A_M { } // RegexGenerator のやつと衝突!
// この衝突を避けるための file private 必要じゃない?
// 以下の2つの名前は衝突しないようにする。
// RegexGenerator の生成物
file private class A_M { } // $<>ファイル名_A_M とかにエンコード?
// DllImportGenerator の生成物
file private class A_M { }
class X
{
//file private ← protected internal の方が長かったわ
//ref ← 行けるようになったとして、さすがに用途的に ref record 使わない?
unsafe protected internal readonly partial record struct S { }
}
配信URL: https://www.youtube.com/watch?v=i2RBGZq0BJU
https://docs.microsoft.com/en-us/visualstudio/releases/2022/release-notes-preview#17.2.0-pre.2.0 https://devblogs.microsoft.com/dotnet/announcing-dotnet-7-preview-2/
いうほど新しい話なさそう… 「Introducing the new Regex Source Generator」に至っては「Preview 1 の頃からあるけどブログにしてなかったわ」のはず。
そして微妙にバグっぽい https://twitter.com/ufcpp/status/1504262994213355522 https://twitter.com/ufcpp/status/1504389869530873857
LDM
ということで配信するなら Language Design Meeting 議事録の話中心になりそうな雰囲気。
Span<char>
に対するパターンマッチSpan
に変換された上で SequenceEquals になってる → 多少キモイけど許容Span<char> s = null;
が OK にもかかわらず) 認めない..
..
と、list spread の..
同じ記号でいい?...
にする案もあるけども..
で行く[main: Attribute]
付けれるようにする案は却下nameof(param)
(メソッドに対する属性とかで nameof を使うとき、引数名を nameof 内で使えるようにする)