01丨轲目苦津代码规范:压行
创建日期:2025-01-11
更新日期:2025-02-04
阅读次数:99
该压行就压行
正确案例:
public static string Hash(this string X) => Convert.ToBase64String(SHA256.HashData(Encoding.UTF8.GetBytes(X)));
错误案例:
public static string Hash(this string X) {
return Convert.ToBase64String(SHA256.HashData(Encoding.UTF8.GetBytes(X)));
}
错误案例:
public static string Hash(this string X) {
var A = Encoding.UTF8.GetBytes(X);
var B = SHA256.HashData(A);
var C = Convert.ToBase64String(B);
return C;
}
原因:压缩代码行数,便于同屏阅读大量代码。 配套代码写作方式:48寸4K显示器,一秒目光可扫全屏三次,同时处理千行代码,外置记忆为【某时要用的代码在某位置】,使得【记忆力强大,需要某代码的时候可以0.1秒内瞬间目光转过去】【无记忆压力,同时记忆千行代码而不吃力,记忆的桎梏不再是大脑的容量、而是视觉的范畴】。 注:外置记忆:不记忆知识的内容,只记忆知识的存在。例如上面的哈希函数,不记忆哈希函数的定义,只记忆哈希函数的用法,甚至可以进一步抽象的只记忆【存在一个文件,里面有一堆安全相关的函数。当我在工作中遇到一个不安全的问题时,如果我对这个问题有一种熟悉感、仿佛我解决过或解决过类似的问题,那么我去扫一眼那个安全文件】。
对于没有记忆方法的人,这样压行后的函数很丑。 对于使用超大显示器+外置记忆法的人,这样压行后的函数很美,可以后天强化记忆力。
不该压行就不要压行
正确案例:
public static string 注释清除(this string X) {
X = X.不可见清除();
X = Regex.Replace(X, @"^\s*\n", string.Empty, RegexOptions.Multiline);(已屏蔽)
X = Regex.Replace(X, @"\/\/.*?$|/\*[\w\W\n]*?\*/", string.Empty, RegexOptions.Multiline);(已屏蔽)
X = Regex.Replace(X, @" +", " ");
X = Regex.Replace(X, @"^\s", string.Empty);
X = Regex.Replace(X, @"\s$", string.Empty);
return X;
}
这里不要合成一行。因为,如果要合成一行的话,有两种方式,两种都不好:
- 使用一个大正则表达式。缺点:看不懂,不好改。除非可以确定那个大正则表达式是完美的、永远无需修改的,否则不要用太大的正则表达式。
- 把大量的Replace放在同一行。缺点:太长了。一行最好不要超过150字符(包括空格)。
配套操作:
- VS界面的宽度为150字符
- 外行思维,让代码与中文描述按行一一对应。对于一个不懂代码的、描述能力强的人,问他哈希的定义是什么,他会一头雾水,所以哈希的定义可以随便压行;但如果问他清除注释的定义是什么,他能说出来【清除多余的空行、双斜杠注释、多余的空格】,他说的每一句话可以写作一行代码。本条操作也可以称之为【让代码与设计稿按行一一对应】,设计稿由不懂编程但懂严谨描述的设计师所描述。
调用时压行:开关面板
功能:E键用于显示/隐藏背包面板 一阶:(直译:当每帧时,如果按下了E键,如果背包开启,那么关闭;否则打开背包)
OnAppUpdate(() => {
if (Input.GetKeyDown(KeyCode.E)) {
if (背包面板.activeSelf) {
背包面板.SetActive(false);
} else {
背包面板.SetActive(true);
}
}
});
二阶:(直译:当每帧时,如果按下了E键,那么切换背包开关状态)
OnAppUpdate(() => {
if (Input.GetKeyDown(KeyCode.E)) {
背包面板.ChangeActive();
}
});
三阶:(直译:设置按键效果,E键对应的效果是切换背包开关状态)
SetKeyDown(KeyCode.E, () => 背包面板.ChangeActive());
四阶:(直译:当E键按下时,切换背包开关状态)
KeyCode.E.OnKeyDown(() => 背包面板.ChangeActive());
配套操作:
- 外行思维。如前文所述,如果一个东西在设计上应当只有一行,那么在代码中也应当只有一行。
调用时压行:加载存档
功能:启动游戏时加载存档 一阶:(大致思路:如果存档文件存在,那么就读取存档文本,然后反序列化为存档结构。否则就新建一个存档)
var 路径 = $"{Application.dataPath}/Saves/{存档名}.json";
存档类 存档;
if (File.Exists(路径)) {
var i = new StreamReader(路径);
var A = i.ReadToEnd();
i.Close();
i.Dispose();
存档 = JsonConvert.DeserializeObject<存档类>(A, new JsonSerializerSettings {
TypeNameHandling = TypeNameHandling.All,
MetadataPropertyHandling = MetadataPropertyHandling.Default,
Formatting = Formatting.Indented,
PreserveReferencesHandling = PreserveReferencesHandling.Objects,(已屏蔽)
ReferenceLoopHandling = ReferenceLoopHandling.Serialize,
});
} else {
存档 = new();
}
二阶:一行代码读取文件
var 路径 = $"{Application.dataPath}/Saves/{存档名}.json";
存档类 存档;
if (File.Exists(路径)) {
var A = File.ReadAllText(路径);
存档 = JsonConvert.DeserializeObject<存档类>(A, new JsonSerializerSettings {
TypeNameHandling = TypeNameHandling.All,
MetadataPropertyHandling = MetadataPropertyHandling.Default,
Formatting = Formatting.Indented,
PreserveReferencesHandling = PreserveReferencesHandling.Objects,(已屏蔽)
ReferenceLoopHandling = ReferenceLoopHandling.Serialize,
});
} else {
存档 = new();
}
三阶:一行代码反序列化
var 路径 = $"{Application.dataPath}/Saves/{存档名}.json";
存档类 存档;
if (File.Exists(路径)) {
存档 = File.ReadAllText(路径).JsonDeserialize<存档类>();
} else {
存档 = new();
}
四阶:三元运算符
var 路径 = $"{Application.dataPath}/Saves/{存档名}.json";
var 存档 = File.Exists(路径) ? File.ReadAllText(路径).JsonDeserialize<存档类>() : new 存档类();
五阶:终极封装
var 存档 = FileRead<存档类>($"Saves/{存档名}.json");
配套操作:
- 外行思维。如前文所述,如果一个东西在设计上应当只有一行,那么在代码中也应当只有一行。【从某某位置加载存档】一句话,那么代码就一行。
总结
基于【超大显示器+外置记忆法+外行思维法】,需要压行。 这样压行有两个好处:
- 强化记忆力,能同时处理千行代码,驾驭五万行的项目。(五万行的项目通常需要同时处理千行左右的代码)
- 无BUG,一遍过。因为使用了外行思维,因此调用的时候几乎不可能有bug,有bug一眼就能看出来;而库如果有bug,那么bug会越改越少,新bug会随着代码规模的扩张而对数式的出现(例如,规模变为十倍,bug变为二倍;规模百倍,bug四倍)(而不压行的话,新bug是线性的,例如,规模变为十倍,bug变为十倍)。