处理大型 if/else 的最佳方式

Best way to handle large if/else

我有一个非常大的 if/else 块,它将对字节数组执行操作。 id 在技术上可以是从 0x001 到 0xFFF 的任何数字,但它们通常是已知的。每个案例都是唯一的,并将对数组中的不同字节执行计算。消息以大约 0.5 毫秒 - 1 毫秒的速率来自队列,并通过此方法进行处理

虽然大 if/else 有效,但我看到的最大问题是,如果在此示例中,id 为 1222,我们必须满足所有先前的 ifs。此外,随着添加的消息越来越多,时间复杂度也会增加,而且会变得非常大。

def calcCanMessage(self):
    while: True
        #get msg - simplified for example
        msgId = msg.id
        msgData = msg.data
        if msgId == 324:
            #do something with msgData
            continue
        elif msgId == 211:
            continue
        elif msgId == 322:
            continue
        elif msgId == 321:
            continue
        elif msgId == 320:
            continue
        elif msgId == 342:
            continue
        elif msgId == 338:
            continue
        elif msgId == 24:
            continue
        elif msgId == 212:
            continue
        elif msgId == 323:
            continue
        elif msgId == 210:
            continue
        elif msgId == 209:
            continue
        elif msgId == 208:
            continue
        elif msgId == 642:
            continue
        elif msgId == 880:
            continue
        elif msgId == 1088:
            continue
        elif msgId == 865:
            continue
        elif msgId == 864:
            continue
        elif msgId == 882:
            continue
        elif msgId == 1595:
            continue
        elif msgId == 1090:
            continue
        elif msgId == 885:
            continue
        elif msgId == 884:
            continue
        elif msgId == 1224:
            continue
        elif msgId == 1761:
            continue
        elif msgId == 1762:
            continue
        elif msgId == 1245:
            continue
        elif msgId == 1219:
            continue
        elif msgId == 1217:
            continue
        elif msgId == 1222:
            continue
        else:
            print('unknown ID: ', msgId)

首先,定义与 msgData 做(不同)事情的函数。函数体将是您当前在 if..else 语句的每个块中所做的任何事情。

def msgId_324(msgData):
    #do something with msgData

def msgId_211(msgData):
    #do something else with msgData

# more functions to handle msgData

然后定义一个字典,将所有消息 ID 值与其对应的函数配对。

msgId_dict = {324: msgId_324, 
            211: msgId_211,
            # more msgId: msg_function pairs
            }

现在您可以用字典查找替换 if 语句,这样会更快,无论有多少消息值,并调用返回的函数。

msgId = msg.id
msgData = msg.data

if msgId in msgId_dict:
    msg_function = msgId_dict[msgId]
    msg_function(msgData)
else:
    # optional else case to handle unrecognized message IDs

正如评论中所建议的那样,将非操作消息 ID 存储在 set:

    ignore_messages = {211, 322, ..., 1222}

    msgId = msg.id
    msgData = msg.data
    if msgId == 324:
        # do something with msgData
    elif msgId not in ignore_messages:
        print('unknown ID: ', msgId)