Ваш код ведет себя как ожидалось. Вы не перевели Java-код на C#. На данный момент я могу заметить одну проблему, но я не знаю, есть ли у них больше, когда вы это исправите.
Ява оригинальный код выходит Петля в то время, когда вход пуст. Ниже то, что код Java выглядит следующим образом:
while (!StdIn.isEmpty()) {
String s = StdIn.readString();
......
......
}
Он использует вход к перерыв из цикла. Выходы, если вход пуст.
Ваш C# код:
while (!s.Equals(""))
{
......
......
}
Он использует s к перерыв из цикла в то время, но s не изменяется где-либо в цикле. Таким образом, цикл продолжается. Это приводит к бесконечному циклу и бесконечному циклу в Unity. = Заблокировать/Заморозить с несколькими исключениями.
Fix # 1. Вызвать Eval в другой теме. Не рекомендуется для новичков.
Fix # 2. Использовать Coroutine.
Мое решение с Coroutine.
Изменить тип возвращаемой функции от double
до Coroutine
затем положить yield return null;
внутри цикла while
. To call функция, использование StartCoroutine(Eval("Your Expression"));
. Использование yield return null;
будет предотвратить Единство от сбоев.
Даже если вы сделаете это, вы код все равно не выйти, когда вы передаете значение, которое не пусто, но это обыкновениеЗамок/Замораживание больше.
Чтобы исправить это и скопировать код с Java, вы должны найти способ выхода из программы с помощью ввода.
Перейти к GameObject ->UI ->Поле ввода и переименовывать, что GameObject в EvalInput;
Теперь используйте поле ввода и код ниже, чтобы код и код C# выглядели как Java-код.Конечный результат сохраняется в глобальной переменной evalResult
.
InputField evalInput;
void Start()
{
StartCoroutine(Eval("Your Expression"));
evalInput = GameObject.Find("EvalInput").GetComponent<InputField>();
}
double evalResult = 0;
public IEnumerator Eval(string expression)
{
Stack<string> ops = new Stack<string>();
Stack<double> vals = new Stack<double>();
string s = expression;
while (!s.Equals(""))
{
s = evalInput.text; //Modify the string here (Empty string == Exit)
if (s.Equals("(")) ;
if (s.Equals("+")) ops.Push(s);
else if (s.Equals("-")) ops.Push(s);
else if (s.Equals("*")) ops.Push(s);
else if (s.Equals("/")) ops.Push(s);
else if (s.Equals("sqrt")) ops.Push(s);
else if (s.Equals(")"))
{
string op = ops.Pop();
double v = vals.Pop();
if (op.Equals("+")) v = vals.Pop() + v;
else if (op.Equals("-")) v = vals.Pop() - v;
else if (op.Equals("*")) v = vals.Pop() * v;
else if (op.Equals("/")) v = vals.Pop()/v;
else if (op.Equals("sqrt")) v = System.Math.Sqrt(v);
vals.Push(v);
}
else vals.Push(double.Parse(s));
yield return null;
}
evalResult = vals.Pop();
}
с очень кратким взглядом, кажется, вы никогда не переустанавливаете 's', и вы зацикливаете бесконечно. – Jonesopolis
Как он «перестает работать»? Когда вы проходите это в отладчике, где/как именно это происходит? – David
Вы называете это внутри функции обновления MonoBehaviour? – Frohlich