有时输出参数非常方便。假设loadData
返回std::vector<T>
并在循环中被调用:
std::pair<ErrorCode,std::vector<T>> loadData();
for (...) {
ErrorCode errorcode;
std::vector<T> data;
std::tie(errorcode,data) = loadData();
}
在这种情况下,loadData
将必须在每次迭代中分配内存。但是,如果传递data
作为输出参数,则可以重新使用先前分配的空间:
ErrorCode loadData(std::vector<T>&);
std::vector<T> data;
for (...) {
ErrorCode errorcode = loadData(data);
}
如果以上内容无关紧要,那么您可能想看看expected<T,E>
。它既代表
- 类型
T
的值,期望值类型;或
- 类型为
E
的值,当发生意外结果时使用的错误类型。
在expected
下,loadData()
签名看起来像:
expected<Data,ErrorCode> loadData();
可以使用C ++ 11实现:https://github.com/TartanLlama/expected
,
错误处理有多种竞争策略。我将不讨论它,因为它超出了问题的范围,但是通过返回错误代码进行错误处理只是一种选择。考虑诸如public class Ball : MonoBehaviour
{
private Rigidbody2D rigidbodyBall;
public SpringJoint2D[] springJoints;
private GameObject speed;
public static Ball instance = null;
#region Life Cycle
void Awake()
{
speed = GameObject.Find("Velocity");
springJoints = GetComponents<SpringJoint2D>();
rigidbodyBall = GetComponent<Rigidbody2D>();
gameManager = GameObject.Find("GameManager").GetComponent<GameManager>();
}
private bool clickedOn = false;
void Update()
{
if (clickedOn)
{
Dragging();
UIManager.instance.pauseButton.SetActive(false);
UIManager.instance.totalScoreUI.gameObject.SetActive(false);
}
else
{
UIManager.instance.pauseButton.SetActive(true);
UIManager.instance.totalScoreUI.gameObject.SetActive(true);
}
}
#endregion
#region Launcher
#region Mouse
void OnMouseDown()
{
SpringJointDeactivate();
clickedOn = true;
}
void OnMouseUp()
{
SpringJointActivate();
clickedOn = false;
SetKinematicState(false);
Invoke("SpringJointDeactivate",0.1f);
}
void Dragging()
{
Vector3 mouseWorldPointStart = transform.position;
Vector3 mouseWorldPoint = Camera.main.ScreenToWorldPoint(Input.mousePosition);
mouseWorldPoint.z = 0f;
if (Boundary.ballInBoundary)
{
transform.position = mouseWorldPoint;
float diffX = mouseWorldPoint.x - mouseWorldPointStart.x;
//TODO
for (int i = 0; i < springJoints.Length; i++)
{
springJoints[i].connectedAnchor = new Vector2(springJoints[i].connectedAnchor.x + diffX,springJoints[i].connectedAnchor.y);
}
}
else
{
Debug.Log("Another situation!");
Debug.Log(Boundary.ballInBoundary);
}
}
#endregion
public void SpringJointActivate()
{
foreach (SpringJoint2D joint in springJoints)
{
joint.enabled = true;
}
}
public void SpringJointDeactivate()
{
foreach (SpringJoint2D joint in springJoints)
{
joint.enabled = false;
}
}
public Vector3[] GetSpringJointsConnectedAnchorCoord()
{
Vector3[] springJointsCoord = new[] { Vector3.zero,Vector3.zero };
for (int i = 0; i < springJoints.Length; i++)
{
springJointsCoord[i] = springJoints[i].connectedAnchor;
}
return springJointsCoord;
}
#endregion
public void SetKinematicState(bool kinematicState)
{
rigidbodyBall.isKinematic = kinematicState;
}
之类的替代方案或异常,它们在C ++中很常见,但在Go中并不常见。
如果您有一个旨在返回Go风格错误代码加值的函数,那么您的std::optional
解决方案在C ++ 11或C + 14中是完美的,尽管在C ++ 17中,您宁愿使用结构化绑定。
,
这样做是否有不利之处(性能或其他方面)?
是的。使用tie
,需要返回值的副本或移动,如果您避免使用tie
,则不需要:
auto result = loadData();
if (std::get<0>(result))
...//error handling
当然,如果您以后再将数据复制或移动到其他地方,例如
data = std::move(std::get<1>(result));
然后使用tie
,因为它更短。
本文链接:https://www.f2er.com/3073355.html