【发布时间】:2020-03-10 18:37:57
【问题描述】:
就上下文而言,我的主要语言是 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 函数的代码本身都会进行查找)?这样做有运行时的好处,还是只是重构代码以适应语言是静态类型的事实?
我相信我了解静态类型 w.r.t 的大部分明显好处。代码可读性、编译时间和运行时的效率——但我不确定如何处理这个特定问题。
简而言之:如何处理函数(返回非基本类型)表明它们在静态类型语言中遇到了不同的错误?
【问题讨论】:
-
各种方式(~“任何可行的方式”)。有关许多 C++ 方法,请参阅stackoverflow.com/questions/3157098/…
-
听起来你需要异常而不是返回值。
-
@FrançoisAndrieux 在一个函数预计会因多种情况而失败的情况下,如何区分不同的情况/失败? (这是
std::variant会被使用的情况吗?) -
@FrançoisAndrieux 啊!优秀的。谢谢你。 :) 如果您将您的 cmets 放入答案中,我会很乐意接受。
-
我应该提一下,您不知何故忘记了将异常作为错误处理机制之一。返回某种
std::variant或std::optional意味着调用者负责解包结果并检查通常不需要的有效值或报告的错误数据。此外,您可能应该将 Ada / Spark 视为正确的静态类型语言。 C/C++ 比较宽松。
标签: python c++ typing static-typing