如何处理静态类型的语言(或一般键入时)的各种错误

问题描述 投票:0回答:1

对于上下文,我的主要语言是Python,而我才刚刚开始使用注释。这是为学习C ++做的准备(并且,从直观上讲,它感觉更好)。


我有这样的东西:

from models import UserLocation
from typing import Optional
import cluster_module
import db
def get_user_location(user_id: int, data: list) -> Optional[UserLocation]:
    loc = UserLocation.query.filter_by(user_id=user_id).one_or_none()
    if loc:
        return loc
    try:
        clusters = cluster_module.cluster(data)
    except ValueError:
        return None # cluster throws an error if there is not enough data to cluster

    if list(clusters.keys()) == [-1]:
        return None # If there is enough data to cluster, the cluster with an index of -1 represents all data that didn't fit into a cluster. It's possible for NO data to fit into a cluster.
    loc = UserLocation(user_id=user_id, location = clusters[0].center)
    db.session.add(loc)
    db.session.commit()
    return loc

因此,我使用typing.Optional来确保在出现错误的情况下可以返回None(如果我正确理解,则此方法的静态键入语言等效项将是返回适当类型的空指针) 。但是,如何区分这两个错误?例如,如果没有足够的数据要集群,我想做的是返回-1,如果有数据,则返回-2,但是没有一个适合集群(或类似的东西)。在Python中,这很容易(因为它不是静态类型的)。即使使用mypy,我也可以说typing.Union[UserLocation, int]

但是,如何用C ++或Java做到这一点? Java程序员是否需要做一些类似的事情,将函数设置为返回int,并返回UserLocation的ID而不是对象本身(然后,使用get_user_location函数的任何代码本身都会进行查找)?这样做是否对运行时有好处,还是只是重组代码以适应语言是静态类型的事实?

我相信我了解静态打字的大部分明显好处。代码的可读性,编译时和运行时的效率,但是我不确定该怎么处理这个问题。

简而言之:如何处理函数(返回非基本类型)以指示它们在静态类型的语言中遇到了不同的错误?

python c++ typing static-typing
1个回答
0
投票

与python解决方案等效的直接C ++将是std::variant<T, U>,其中T是预期的返回值,而U是错误代码类型。然后,您可以检查变体包含哪种类型,然后从那里去。例如:

#include <cstdlib>
#include <iostream>
#include <string>
#include <variant>

using t_error_code = int;

std::variant<std::string, t_error_code> foo()
{
    // Returns error 10
    //return 10;

    // Returns the string
    return "Hello, World!";
}

int main()
{
    auto result = foo();

    // Python : if isinstance(result, t_error_code)
    if (std::holds_alternative<t_error_code>(result))
    {
        const auto error_code = std::get<t_error_code>(result);
        std::cout << "error " << error_code << std::endl;
        return EXIT_FAILURE;
    }

    std::cout << std::get<std::string>(result) << std::endl;
}

但是在实践中却很少见到。如果期望某个函数失败,则单个失败的返回值(例如nullptrend迭代器)就足够了。这样的失败是预料之中的,不是错误。如果意外失败,则首选例外,这也可以消除您在此处描述的问题。期望失败并关心失败发生原因的细节都是不寻常的。

© www.soinside.com 2019 - 2024. All rights reserved.