对于上下文,我的主要语言是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 ++将是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;
}
但是在实践中却很少见到。如果期望某个函数失败,则单个失败的返回值(例如nullptr
或end
迭代器)就足够了。这样的失败是预料之中的,不是错误。如果意外失败,则首选例外,这也可以消除您在此处描述的问题。期望失败并关心失败发生原因的细节都是不寻常的。