*
Как видно из названия, возникает такой тип ошибки, когда вы, скорее всего, пытаетесь перебрать или найти значение из массива с не- существующий ключ.
Считаем, что вы пытаетесь показать каждую букву из $string
$string = 'ABCD';
for ($i=0, $len = strlen($string); $i <= $len; $i++){
echo "$string[$i] \n";
}
. Вышеприведенный пример сгенерирует ( онлайн-демонстрацию ):
A
B
C
D
Notice: Uninitialized string offset: 4 in XXX on line X
И, как только скрипт заканчивается эхом D
, вы получите ошибку, потому что внутри цикла for()
вы сказали PHP, чтобы показать вам от первого до пятого символа строки из 'ABCD'
Что, существует, но поскольку цикл начинает отсчитываться от 0
и эха D
к моменту достижения значения 4
, он выдает ошибку смещения.
Аналогичные ошибки:
Возможно, это сделает его более ясным:
public class SomeClass
{
static void foo(int x) { }
static void foo(string s) { }
static void bar<T>(Action<T> f){}
static void barz(Action<int> f) { }
static void test()
{
Action<int> f = foo;
bar(f);
barz(foo);
bar(foo);
//these help the compiler to know which types to use
bar<int>(foo);
bar( (int i) => foo(i));
}
}
нечто не является действием - нечто является группой метода.
Редактирование: я добавил еще два способа помочь компилятору выяснить тип (т.е. - как пропустить шаги вывода).
От моего чтения статьи в ответе JSKEET, решение не вывести тип, кажется, основано на взаимном выводящем сценарии, такой как
static void foo<T>(T x) { }
static void bar<T>(Action<T> f) { }
static void test()
{
bar(foo); //wut's T?
}
, Так как общая проблема была, не решают - способный, они выбирают к левым определенным проблемам, где решение существует как нерешенное.
В результате этого решения, Вы не будете добавлять перегрузку для метода и получать много беспорядка типа от всех вызывающих сторон, которые привыкли к единственной членской группе метода. Я предполагаю, что это - хорошая вещь.
Обоснование состоит в том, что, если тип когда-нибудь расширяется, не должно быть никакой возможности отказа. т.е. если нечто метода (строка) добавляется к типу, это никогда не должно иметь значения для существующего кода - пока содержание существующих методов не изменяется.
По этой причине, даже когда существует только одно нечто метода, ссылка на нечто (известный как группа метода) не может быть брошена делегату non-type-specific, такой как Action<T>
, но только определенному для типа делегату такой как Action<int>
.
Это немного нечетно, да. Спецификацию C# 3.0 для вывода типа трудно считать и имеет ошибки в нем, но это взгляды как он должно работать. В первой фазе (разделяют 7.4.2.1) я полагаю, что существует ошибка - это не должно упоминать группы метода в первом маркере (поскольку они не покрыты явным выводом типа параметра (7.4.2.7) - что означает, что это должно использовать выходной вывод типа (7.4.2.6). То, что взгляды как он должны работать - но очевидно это не делает: (
я знаю, что MS надеется улучшать спецификацию для вывода типа, таким образом, это могло бы стать немного более ясным. Я также знаю, что независимо от трудности чтения его, существуют ограничения на группы метода и вывод типа - ограничения, которые могли быть специальными в корпусе, когда группа метода является только на самом деле отдельным методом по общему признанию.
у Eric Lippert есть запись в блоге на вывод типа возврата, не работающий с группами метода , который является подобен к этому случаю - но здесь мы не интересуемся типом возврата, только на типе параметра. Возможно, что другие сообщения в его серии вывода типа могут помочь все же.
Имейте в виду, что задание
Action<int> f = foo;
уже содержит много синтаксического сахара. На самом деле компилятор генерирует код для этого оператора:
Action<int> f = new Action<int>(foo);
Соответствующий вызов метода компилируется без проблем:
bar(new Action<int>(foo));
Fwiw, поэтому помогает компилятору вывести аргумент типа:
bar<int>(foo);
Таким образом, все сводится к вопросу, почему сахар в операторе присваивания, а не в вызове метода? Я должен был бы предположить, что это потому, что сахар однозначен в задании, есть только одна возможная замена. Но в случае вызовов методов авторам компилятора уже приходилось сталкиваться с проблемой разрешения перегрузки. Правила которых довольно сложны. Они, вероятно, просто не удосужились.