Re: [討論] 寫三元判斷式code review被打槍
看板Soft_Job (軟體人)作者CloudyWing (孤單ㄉ翼)時間2年前 (2022/12/28 00:16)推噓0(13推 13噓 47→)留言73則, 40人參與討論串13/15 (看更多)
這邊不針對效能,也不針對說階層太多,應該用什麼方式重構之類的
只是看到有人提到巢狀的三元運算子,閱讀性太差,應該改回用if else寫
我只是好奇兩者的可讀性有差很多嗎?
以下只是舉例,不是指實務上會真的這樣寫
(1) 三元運算子:
int i = condition1
    ? condition2
        ? condition3
            ? 1
            : 2
        : 3
    : 4;
(2) if else:
int i;
if (condition1)  {
    if (condition2) {
        if (condition3) {
            i = 1;
        } else {
            i = 2;
        }
    } else {
        i = 3;
    }
} else {
    i = 4;
}
單就上面的範例來說,我覺得兩者可讀性差不多,還是只是因為我看習慣產生的錯覺 XD
以我自己的觀點來看,像這種條件式指派單一變數值的情境,三元寫起來比較順手
也不用擔心像在寫 if else 時,因漏寫了 else 導致有情況沒指派到值
--
※ 發信站: 批踢踢實業坊(ptt.cc), 來自: 203.204.160.44 (臺灣)
※ 文章網址: https://www.ptt.cc/bbs/Soft_Job/M.1672157770.A.D00.html
→
12/28 00:18, 
                                2年前
                            , 1F
12/28 00:18, 1F
噓
12/28 01:20, 
                                2年前
                            , 2F
12/28 01:20, 2F
噓
12/28 01:34, 
                                2年前
                            , 3F
12/28 01:34, 3F
噓
12/28 01:45, 
                                2年前
                            , 4F
12/28 01:45, 4F
噓
12/28 01:57, 
                                2年前
                            , 5F
12/28 01:57, 5F
老實說我也是覺得明顯一比較好啊
只是看前面文章和推文,想說講差不多來測一下風向 XD
推
12/28 03:35, 
                                2年前
                            , 6F
12/28 03:35, 6F
→
12/28 07:50, 
                                2年前
                            , 7F
12/28 07:50, 7F
→
12/28 08:10, 
                                2年前
                            , 8F
12/28 08:10, 8F
→
12/28 08:31, 
                                2年前
                            , 9F
12/28 08:31, 9F
→
12/28 08:42, 
                                2年前
                            , 10F
12/28 08:42, 10F
→
12/28 08:44, 
                                2年前
                            , 11F
12/28 08:44, 11F
推
12/28 08:50, 
                                2年前
                            , 12F
12/28 08:50, 12F
→
12/28 08:50, 
                                2年前
                            , 13F
12/28 08:50, 13F
實務上來說我也是會用 Array Map,或是拆成 Function 來攤平巢狀結構
大部分的情況下寫到兩層就是極限
而且真寫成巢狀,以這案例會在 Condition 加 Not 來對調順序
所以從推文來看,問題點不在巢狀三元,而是只要是寫成多重巢狀都不好閱讀
有些情境在相同結構下,反而有人會覺得改寫 if else 卻降低可讀性
→
12/28 09:20, 
                                2年前
                            , 14F
12/28 09:20, 14F
→
12/28 10:03, 
                                2年前
                            , 15F
12/28 10:03, 15F
就看到前面說巢狀三元可讀性劣於if else
所以故意寫一個很醜的結構來看一下相同結構下,是否真的三元比較難閱讀 XD
推
12/28 11:07, 
                                2年前
                            , 16F
12/28 11:07, 16F
→
12/28 11:08, 
                                2年前
                            , 17F
12/28 11:08, 17F
噓
12/28 11:14, 
                                2年前
                            , 18F
12/28 11:14, 18F
推
12/28 11:20, 
                                2年前
                            , 19F
12/28 11:20, 19F
噓
12/28 11:33, 
                                2年前
                            , 20F
12/28 11:33, 20F
噓
12/28 12:02, 
                                2年前
                            , 21F
12/28 12:02, 21F
噓
12/28 12:30, 
                                2年前
                            , 22F
12/28 12:30, 22F
→
12/28 12:30, 
                                2年前
                            , 23F
12/28 12:30, 23F
※ 編輯: CloudyWing (61.216.190.109 臺灣), 12/28/2022 13:21:11
→
12/28 13:21, 
                                2年前
                            , 24F
12/28 13:21, 24F
※ 編輯: CloudyWing (61.216.190.109 臺灣), 12/28/2022 13:41:25
→
12/28 13:36, 
                                2年前
                            , 25F
12/28 13:36, 25F
我認真說,如果是專案公司,你可能高估了正常人的水平了
多的是能動就好(嘆氣
以我的經驗,我之前同事如果修改要在 if 內部加判斷就直接加了
多半不會條件反轉
另外 else if 本身就是巢狀的,有些程式語言本身沒有提供 else if 語法
它們的 else if 是以下程式碼排版後產生看起來攤平的效果
if (condition1) {
} else {
    if (condition2) {
    }
}
而且兩種寫法都反轉後,if else 也真未必有比較好閱讀
例如:
三元運算子:
int i = condition1
    ? 1
    : condition2
        ? 2
        : condition3
            ? 3
            : 4;
if else:
int i;
if (condition1) {
    i = 1;
} else if (condition2) {
    i = 2;
} else if (condition3) {
    i = 3
} else {
    i = 4;
}
→
12/28 13:42, 
                                2年前
                            , 26F
12/28 13:42, 26F
※ 編輯: CloudyWing (61.216.190.109 臺灣), 12/28/2022 14:20:13
推
12/28 14:23, 
                                2年前
                            , 27F
12/28 14:23, 27F
→
12/28 14:23, 
                                2年前
                            , 28F
12/28 14:23, 28F
推
12/28 14:40, 
                                2年前
                            , 29F
12/28 14:40, 29F
→
12/28 14:54, 
                                2年前
                            , 30F
12/28 14:54, 30F
→
12/28 14:55, 
                                2年前
                            , 31F
12/28 14:55, 31F
→
12/28 14:57, 
                                2年前
                            , 32F
12/28 14:57, 32F
噓
12/28 15:14, 
                                2年前
                            , 33F
12/28 15:14, 33F
推
12/28 15:57, 
                                2年前
                            , 34F
12/28 15:57, 34F
推
12/28 16:20, 
                                2年前
                            , 35F
12/28 16:20, 35F
→
12/28 16:28, 
                                2年前
                            , 36F
12/28 16:28, 36F
→
12/28 16:35, 
                                2年前
                            , 37F
12/28 16:35, 37F
→
12/28 18:03, 
                                2年前
                            , 38F
12/28 18:03, 38F
噓
12/28 18:50, 
                                2年前
                            , 39F
12/28 18:50, 39F
剛 Google 一下,Guard Clauses 我也很愛用
只是我之前不知道它叫 Guard Clauses
噓
12/28 20:22, 
                                2年前
                            , 40F
12/28 20:22, 40F
這邊來說明一下 else if 是怎麼來的
1.
完整程式長這樣:
if (condition1) {
} else {
    if (condition2) {
    } else {
    }
}
2.
我們已知 else 後面只有單行可以不用加大括弧,而 if else 語句將之視為一個單行
所以我們將第一個 else 的大括弧去掉變成以下這樣
if (condition1) {
} else
    if (condition2) {
    } else {
    }
}
3. 最後再用排版將第二個 if 放置在第一個 else 後面,else if 就誕生了
if (condition1) {
} else if (condition2) {
} else {
}
所以我前面說 else if 本質上還是巢狀結構,只是靠排版攤平
不過有些程式語言像 PHP 是真的有提供 elseif 這個關鍵詞
推
12/28 21:22, 
                                2年前
                            , 41F
12/28 21:22, 41F
→
12/28 22:00, 
                                2年前
                            , 42F
12/28 22:00, 42F
推
12/28 22:12, 
                                2年前
                            , 43F
12/28 22:12, 43F
本文一開始就加一堆但書,並註名只是舉例,非實務上的寫法 XD
實際上當然是 Array Map、Function 和 Guard Clauses 等方法來優化寫法 XD
推文提到的比較好的寫法,才是我實務上真正在寫的
大部分情況我最多只會寫到兩層,且不會用成波動拳結構
我只是因為前面文章有推文提到巢狀三元運算子容易漏看,且不好閱讀
而改回寫成 if else
關於容易漏看這部分我是疑惑為什麼會容易漏看
至於可讀性部分,兩種方法當然都很糟
但看起來也不是每個人都認為巢狀 if else 可讀性優於巢狀三元運算子
實際上真正影響閱讀的多層巢狀這件事,真的多層巢狀起來
if else 和 三元運算子都不好閱讀
※ 編輯: CloudyWing (203.204.160.44 臺灣), 12/28/2022 23:35:33
→
12/28 23:40, 
                                2年前
                            , 44F
12/28 23:40, 44F
噓
12/29 00:07, 
                                2年前
                            , 45F
12/29 00:07, 45F
→
12/29 00:07, 
                                2年前
                            , 46F
12/29 00:07, 46F
→
12/29 00:08, 
                                2年前
                            , 47F
12/29 00:08, 47F
→
12/29 00:10, 
                                2年前
                            , 48F
12/29 00:10, 48F
→
12/29 01:24, 
                                2年前
                            , 49F
12/29 01:24, 49F
→
12/29 01:24, 
                                2年前
                            , 50F
12/29 01:24, 50F
→
12/29 01:24, 
                                2年前
                            , 51F
12/29 01:24, 51F
→
12/29 01:24, 
                                2年前
                            , 52F
12/29 01:24, 52F
推
12/29 04:03, 
                                2年前
                            , 53F
12/29 04:03, 53F
→
12/29 04:03, 
                                2年前
                            , 54F
12/29 04:03, 54F
噓
12/29 04:07, 
                                2年前
                            , 55F
12/29 04:07, 55F
→
12/29 08:38, 
                                2年前
                            , 56F
12/29 08:38, 56F
→
12/29 12:40, 
                                2年前
                            , 57F
12/29 12:40, 57F
推
12/29 13:45, 
                                2年前
                            , 58F
12/29 13:45, 58F
→
12/29 13:46, 
                                2年前
                            , 59F
12/29 13:46, 59F
→
12/29 13:46, 
                                2年前
                            , 60F
12/29 13:46, 60F
→
12/29 13:47, 
                                2年前
                            , 61F
12/29 13:47, 61F
→
12/29 13:48, 
                                2年前
                            , 62F
12/29 13:48, 62F
→
12/29 21:02, 
                                2年前
                            , 63F
12/29 21:02, 63F
→
12/29 21:02, 
                                2年前
                            , 64F
12/29 21:02, 64F
→
12/29 21:02, 
                                2年前
                            , 65F
12/29 21:02, 65F
→
12/30 07:08, 
                                2年前
                            , 66F
12/30 07:08, 66F
→
12/30 07:11, 
                                2年前
                            , 67F
12/30 07:11, 67F
→
12/30 07:12, 
                                2年前
                            , 68F
12/30 07:12, 68F
→
12/30 07:12, 
                                2年前
                            , 69F
12/30 07:12, 69F
→
12/30 09:18, 
                                2年前
                            , 70F
12/30 09:18, 70F
→
12/30 09:18, 
                                2年前
                            , 71F
12/30 09:18, 71F
推
12/30 12:04, 
                                2年前
                            , 72F
12/30 12:04, 72F
→
12/30 16:38, 
                                2年前
                            , 73F
12/30 16:38, 73F
討論串 (同標題文章)
完整討論串 (本文為第 13 之 15 篇):
Soft_Job 近期熱門文章
PTT職涯區 即時熱門文章
                            18
                        
                            30