|
Небольшой вопрос по Go | ☑ | ||
---|---|---|---|---|
0
Renat11111
25.12.19
✎
15:53
|
Кто разбирается помогите понять основу. Есть пакет io
В нем определяется интерфейс reader и соответственно его метод Read type Reader interface { Read(p []byte) (n int, err error) } в пакете String следующее func (r *Reader) Read(b []byte) (n int, err error) { if r.i >= int64(len(r.s)) { return 0, io.EOF } r.prevRune = -1 n = copy(b, r.s[r.i:]) r.i += int64(n) return } Правильно ли я понимаю что в изначальном пакете io что то типа обертки метода а метод доопределяется в каждом пакете? Извиняюсь за наивные вопросы просто в начале пути не хочу чтобы в голове складывалось неверное представление |
|||
1
Asmody
25.12.19
✎
16:01
|
это точно канал про анимэ?
|
|||
2
Garykom
гуру
25.12.19
✎
16:04
|
(0) Нет интерфейс Reader и структура Reader из разных пакетов не связаны.
type Reader A Reader implements the io.Reader, io.ReaderAt, io.Seeker, io.WriterTo, io.ByteScanner, and io.RuneScanner interfaces by reading from a string. The zero value for Reader operates like a Reader of an empty string. type Reader struct { // contains filtered or unexported fields } |
|||
3
Garykom
гуру
25.12.19
✎
16:07
|
(2)+ Привязка идет по "Read" в Go https://ru.wikipedia.org/wiki/Утиная_типизация
|
|||
4
Garykom
гуру
25.12.19
✎
16:09
|
(3)+ Т.е. любая структура которая реализует "Read(p []byte) (n int, err error)" будет иметь интерфейс "Reader".
И неважно какое имя мы дали этой структуре, ну вот захотелось им и обозвали тоже Reader. |
|||
5
Renat11111
25.12.19
✎
16:17
|
r := strings.NewReader("my request")
Тоесть получается тут r структура Но так как у структуры есть метод Read Структура данная является и интерфейсом? или опять я не прав? |
|||
6
Garykom
гуру
25.12.19
✎
16:21
|
(5) Да r тут структура имеющая интерфейс Reader (с одним методом Read).
И везде в другом коде где известно про интерфейс Reader, можно подсунуть r (который фактически реализует этот интерфейс). |
|||
7
Garykom
гуру
25.12.19
✎
16:23
|
(5) Но структура не является интерфейсом!
Она реализует интерфейс, т.у. у данной структуры есть метод (или набор всех необходимых методов) и поэтому она обладает объявленным с этими методами интерфейсом. |
|||
8
trad
25.12.19
✎
16:27
|
(5) эта структура не является, а реализует интерфейс.
указатель на нее можно передать например в такую функцию func foo(r io.Reader) { } r := strings.NewReader("my request") foo(r) |
|||
9
Garykom
гуру
25.12.19
✎
16:28
|
Например в своем коде ты можешь написать
type MistaR struct { // ... } func (m *MistaR ) Read(b []byte) (n int, err error) { if m.i >= int64(len(m.s)) { return 0, io.EOF } m.prevRune = -1 n = copy(b, m.s[m.i:]) m.i += int64(n) return } А затем имея массив или слайс где внутри хрен знат что или "type Reader struct" или "type MistaR struct" не парясь получив элемент делать element.Read(b) Или передавать в любой сторонний модуль/код где знают про "type Reader interface" и будут дергать этот метод Read (хотя про твою структуру MistaR там слыхом не слыхивали) |
|||
10
Renat11111
25.12.19
✎
16:29
|
Круто! многое понял Хорошо ответили мне а то бы в неверном направлении пошел Спасибо
|
|||
11
Garykom
гуру
25.12.19
✎
16:31
|
||||
12
Renat11111
25.12.19
✎
16:34
|
(11) Еще раз огромное спасибо
|
|||
13
Garykom
гуру
25.12.19
✎
16:35
|
(8) Забыл уточнить что внутри "func foo(r io.Reader)" низзя ничего кроме r.Read() делать с r
Т.е. только те методы вызывать которые прописаны у интерфейса io.Reader |
|||
14
trad
25.12.19
✎
17:21
|
(13) конечно, то что можно делать с параметром, определяется его типом - r io.Reader
|
|||
15
Renat11111
25.12.19
✎
17:29
|
Небольшое уточнение то есть главный плюс интерфеса в что я в любую функцию с параметрами r Reader Могу передать свою переменную r или MistaR Например io.ReadFull Я прав?
|
|||
16
trad
25.12.19
✎
17:32
|
можешь, если в качестве параметра указан интерфейс, а переменная имеет тип который ему удовлетворяет
|
|||
17
pechkin
25.12.19
✎
17:40
|
поясните за синтаксис
что за 2 параметра у функции |
|||
18
Renat11111
25.12.19
✎
17:58
|
(17) если вы про (15) То тут https://habr.com/ru/company/mailru/blog/463063/ реально все доходчиво объясняется
|
|||
19
pechkin
25.12.19
✎
18:02
|
это так методы объектов задаются чтоли?
|
|||
20
pechkin
25.12.19
✎
18:03
|
зачем какждый раз придумывают новый синтаксис для типовых вещей?
|
|||
21
pechkin
25.12.19
✎
18:09
|
нет чтоб просто писать
func Reader.Read(b []byte) (n int, err error) |
|||
22
pechkin
25.12.19
✎
18:10
|
а вместо имени переменной писать this ну или self
|
|||
23
Garykom
гуру
25.12.19
✎
19:07
|
(17) Параметр у функции один "b []byte"
"n int, err error" это описание возвращаемых результатов функции |
|||
24
Сияющий в темноте
25.12.19
✎
23:52
|
просто,в нормальном языке были бы одни скобки и IN или OUT перед параметрами.
|
|||
25
Garykom
гуру
26.12.19
✎
00:04
|
(24) Это лишнее, зачем писать IN и OUT когда порядком скобок все определяется?
|
|||
26
Garykom
гуру
26.12.19
✎
00:06
|
(25)+ Немного путано только выходи если функция без параметров но с результатом
func MyFun1()(n int){ } Если же "процедура" то банально можно опустить вторые скобки func MyProc1(){ } |
|||
27
Asmody
26.12.19
✎
00:10
|
(24) вторые скобки описывают _тип_ возвращаемого значения. Или, если угодно, контракт. Написано ([]int, string) - значит функция обязуется вернуть массив целых и строку. И ничего иного. Компилятор проверит.
|
|||
28
Asmody
26.12.19
✎
00:12
|
(27)+ причём, компилятор проверит, что любой return возвращает что надо, и там, где функция вызвана, готовы принять то, что она вернёт
|
|||
29
Garykom
гуру
26.12.19
✎
00:13
|
(27) Он подразумевал что IN или OUT в одних скобках, как ByVal или ByRef
func (m *MistaR ) Read(IN b []byte, OUT n int, err error) { } Да такой вариант синтаксиса вполне рабочий но не в Golang |
|||
30
LinuxOrg
26.12.19
✎
00:17
|
(1) это уже давно не форум по 1С. Люди массово валят. Теперь в go.
Вообще более конструктивно здесь создать канал поддержки продуктов от Smartbear и Atlassian |
|||
31
Garykom
гуру
26.12.19
✎
00:19
|
(30) Smartbear можно для работы с 1С применять?
Atlassian знаю что юзают, первый бит например на их продуктах сидят плотно. |
|||
32
Asmody
26.12.19
✎
00:19
|
(30) создай, это недорого. Фузинята не дадут соврать.
|
|||
33
Garykom
гуру
26.12.19
✎
00:20
|
(32) И почем оптом если отдельный раздел с неограниченным числом веток?
|
|||
34
Garykom
гуру
26.12.19
✎
00:21
|
(33)+ И это личка/админка с автооплатой и автовыставлением счетов есть уже?
|
|||
35
Garykom
гуру
26.12.19
✎
00:22
|
(33)+ И главное API не забыть для автоматизации модерирования и холивара накидыванием новых постов программно.
Чтобы AI прикрутить на ML. |
|||
36
arsik
гуру
26.12.19
✎
08:16
|
Я так понял интерфейсы нужны для составных типов - аналог 1С. В go строгая типизация, и что бы обойти это нужны интерфейсы.
|
|||
37
Сияющий в темноте
26.12.19
✎
09:24
|
интерфейсы нужны тогда,когда нет множественного наследования,а хочется,чтобы класм реализовывал несколько базовых поведений.
что касается возврата нескольких значений,то можно считать,что фкнкция возвращает структуру,состоящую из этих значений,так как такие функции все равно в выражение не подставишь. |
|||
38
Asmody
26.12.19
✎
09:27
|
(36) Не совсем так. С помощью интерфейсов в go (и не только) реализуется полиморфизм. Проще говоря, компилятор может проверить, что то, что прилетело в функцию, будет иметь свойства и методы, которые в этой функции используются. Чтобы получить ошибку типа одинесовского "Значение не является значением объектного типа" в go надо сильно постараться.
|
|||
39
Asmody
26.12.19
✎
09:46
|
(37) В go функции очень хорошо подставляются в выражение. В go вдоль и поперек пишут такое:
res, err := someFunc() if err != nil ... Более того, поскольку в go функции первого класса, то вполне возможны такая конструкция: func someF(initialState string) func(next http.Handler) http.Handler {...} - функция возвращает функцию, которая принимает и возвращает http.Handler |
|||
40
ДенисЧ
26.12.19
✎
09:58
|
(39) Из языка стремительно делают write-only язык...
|
|||
41
pechkin
26.12.19
✎
10:07
|
а получается что в го никак не контролируется что объект соотвествует интерфейсу?
|
|||
42
pechkin
26.12.19
✎
10:08
|
(40) в жс тоже можно писать
[а, b, c] =myFunc() |
|||
43
ДенисЧ
26.12.19
✎
10:10
|
(42) А никто не говорит, что жс - хороший читабельный язык ))
|
|||
44
Garykom
гуру
26.12.19
✎
10:11
|
(41) В Go нету объектов по сути, есть экземпляры типов (структур).
Контролируется что если методы который реализованы для структуры соответствуют некоему интерфейсу, значит эта структура и все ее экземпляры имеют этот интерфейс. |
|||
45
Garykom
гуру
26.12.19
✎
10:14
|
(44)+ Т.е. не надо явно и заранее иерархию выстраивать классов или явно интерфейс прописывать-реализовывать.
Можно ваще ход конем сделать, взять любой чужой тип (структуры) и накрутить требуемые для интерфейса методы - опс чужой тип заимел нужный интерфейс и можно куда то подсунуть. |
|||
46
pechkin
26.12.19
✎
10:18
|
(44) вопрос в обратном порядке.
вот в интерфейс добавили метод, как узнать что все объекты-структуры сломались? |
|||
47
Asmody
26.12.19
✎
11:10
|
(46) компиляция не пройдёт
|
|||
48
pechkin
26.12.19
✎
11:11
|
(47) а как он узнает, что структура реализует интерфейс?
|
|||
49
pechkin
26.12.19
✎
11:12
|
типа если я реализую 1 функцию из интерфейса, то должен и все?
|
|||
50
Garykom
гуру
26.12.19
✎
11:35
|
(49) Не должен, но если хочешь чтобы структура реализовала данный интерфейс надо да все "функции" (методы) реализовать из этого интерфейса
|
|||
51
Asmody
26.12.19
✎
11:35
|
(48) Это называется "утиная типизация". В go ты явно нигде не указываешь, что "структура реализует интерфейс", в отличие от тех же java/c#.
Но если структура реализует методы интерфейса, то считается, что структура реализует интерфейс. Соответственно, её можно использовать там, где программа ожидает этот интерфейс. |
|||
52
Garykom
гуру
26.12.19
✎
11:36
|
(50) *чтобы структура имела данный интерфейс
|
|||
53
Garikk
26.12.19
✎
11:39
|
(51) (52) забавно, типа я написаел 100500 ф-ций с этим интерфейсом, потом добавляю какоето новое поле в него (но ф-ции не меняю), всё хоть развалится при компиляции?
|
|||
54
Garykom
гуру
26.12.19
✎
11:40
|
(53) Конечно развалится, ошибку напишет при попытке скомпилировать.
|
|||
55
Asmody
26.12.19
✎
11:40
|
(53) Ну да. Развалится при компиляции, но не в реалтайме.
|
|||
56
Garikk
26.12.19
✎
11:41
|
чтото мне сложно понять как он узнает что ф-ция имплементирует какойто интерфейс
|
|||
57
Garikk
26.12.19
✎
11:41
|
если его явно не указывать
|
|||
58
Garykom
гуру
26.12.19
✎
11:42
|
(56) (57) Виртуальная табличка строится
|
|||
59
Garykom
гуру
26.12.19
✎
11:43
|
(58) "Если это выглядит как утка, плавает как утка и крякает как утка, то это, вероятно, и есть утка."
|
|||
60
Asmody
26.12.19
✎
11:43
|
(56) имплементирует структура, а не функция.
а узнать это просто: интерфейс - суть список имен. у структуры тоже есть список имен. сравнить два списка занятие нехитрое |
|||
61
Garikk
26.12.19
✎
11:43
|
(58) а если у меня динамический вызов процедур, он магически догадается что я именно эту процедуру по именно этому интерфейсу вызову?
|
|||
62
Garikk
26.12.19
✎
11:44
|
(59) красиво звучит, но в яве тоже самое но там надо писать implements
|
|||
63
Garykom
гуру
26.12.19
✎
11:44
|
(61) Функции не имеют интерфейсов см (60)
|
|||
64
Asmody
26.12.19
✎
11:45
|
(61) процедуры тоже типизированы
|
|||
65
pechkin
26.12.19
✎
11:46
|
т.е такой код будет валиться
type Reader interface { Read(p []byte) (n int, err error) Write(p []byte) (n int, err error) } в пакете String следующее func (r *Reader) Read(b []byte) (n int, err error) { if r.i >= int64(len(r.s)) { return 0, io.EOF } r.prevRune = -1 n = copy(b, r.s[r.i:]) r.i += int64(n) return } ибо не реализован метод Write, так? |
|||
66
Garikk
26.12.19
✎
11:46
|
блин чем дальше лезу в го тем больше считаю что они там все наркоманы
|
|||
67
Garykom
гуру
26.12.19
✎
11:46
|
(62) Неа в яве как и в C# (там утиная типизация сторонними хаками только) и прочих многих явная типизация через implements.
Там ты если написал implements то обязан все методы из него реализовать или ошибка компиляции. В Go же не надо писать implements, но если ты реализовал все методы из него то считается что виртуально "написал implements" |
|||
68
pechkin
26.12.19
✎
11:47
|
по мне так строгое указание все-таки нагляднее
|
|||
69
Garikk
26.12.19
✎
11:48
|
(68) вот +100500... мозг конечно ломается на том что они выкинули классы и пытаются странными магическими пассами реализовать их функционал
|
|||
70
Asmody
26.12.19
✎
11:48
|
(62) Ну да. В java явная реализация интерфейсов. Но в go гибче.
Допустим, у тебя есть два интерфейса, у которых методы частично пересекаются. И структура, которая реализует эти методы. Тогда она реализует и интерфейс1 и интерфес2. |
|||
71
pechkin
26.12.19
✎
11:48
|
(67) а можно ли не все методы реализовать?
|
|||
72
Garykom
гуру
26.12.19
✎
11:48
|
(66) Ыыыы, неа просто у тебя основы алгоритмов и реализаций на низком уровне слабые знания.
В Go наборот вернулись назад и явно показывают программеру как оно реально работает, а не скрывается все в реализации некоего языка на конкретной JVM или компилятором в рантайме. |
|||
73
Garikk
26.12.19
✎
11:49
|
(72) на самом деле ты делаешь неверные выводы лишь по тому что тебе оифгеть как го нравится, а комуто не нравится
|
|||
74
Asmody
26.12.19
✎
11:49
|
(71) можно. но тогда структура не будет реализовывать интерфейс
|
|||
75
Garykom
гуру
26.12.19
✎
11:49
|
(71) Можно не все, но тогда считается что интерфейс не реализован еще.
Но возможно реализовав не все методы ты уже сделал некий другой более простой интерфейс. |
|||
76
pechkin
26.12.19
✎
11:49
|
(72) в рантайме никаких интерфейсов нет
|
|||
77
Garikk
26.12.19
✎
11:49
|
(70) в яве тоже можно делать несколько интерфейсов какбы
|
|||
78
pechkin
26.12.19
✎
11:50
|
(74) но тогда не понятно как компилятор узнает, что стурктура перестала реализовывать интерфейс
|
|||
79
Garykom
гуру
26.12.19
✎
11:50
|
(76) Речь не только про интерфейсы но и про слайсы на которых многие срезаются и недопонимают и еще кучу моментов.
|
|||
80
Asmody
26.12.19
✎
11:50
|
(78) Я же написал - сравниваются списки имен
|
|||
81
Garikk
26.12.19
✎
11:51
|
(72) < явно показывают программеру как оно реально работает>
реально не существует ни функций ни объектов, есть поток комманд с условными и безусловными переходами |
|||
82
Garykom
гуру
26.12.19
✎
11:51
|
(78) Виртуальная таблица интерфейсов не будет содержать структуры и структурам не присвоится признак реализации интерфейса при компиляции
|
|||
83
pechkin
26.12.19
✎
11:51
|
(80) вопрос в том а как он понимает что должна была таки реализовать?
|
|||
84
Garykom
гуру
26.12.19
✎
11:54
|
(81) Не совсем так, есть промежуточная прокладка.
На совсем низком уровне да "поток комманд с условными и безусловными переходами". Java и прочие это слишком высокий уровень абстракции, а Go ближе к среднему, где прямо дают доступ к реально как оно работающим реализациям этих абстракций. |
|||
85
Asmody
26.12.19
✎
11:54
|
(83) так у тебя объявляется переменная или параметр типа интерфейс. потом ты присваиваешь что-то переменной. компилятор сравнивает ожидаемый набор имен из интерфейса с набором имен того, что ты пытаешься запихнуть в переменную
|
|||
86
pechkin
26.12.19
✎
11:57
|
те пока не использую где-тодальше все норм.
как начинаю использовать получаю ошибку |
|||
87
Garikk
26.12.19
✎
12:01
|
(85) <потом ты присваиваешь что-то переменной>
так это может происходить неявно |
|||
88
Garikk
26.12.19
✎
12:02
|
*всмысле для компилятора неявно
|
|||
89
pechkin
26.12.19
✎
12:02
|
(87) Это как это неявно?
|
|||
90
Garikk
26.12.19
✎
12:03
|
(89) ну в го например есть динамический импорт библиотек?
|
|||
91
pechkin
26.12.19
✎
12:03
|
пример кода приведи на питоне хотябы
|
|||
92
Garikk
26.12.19
✎
12:06
|
ну вот на яве, может конечно на го такого не бывает
берем массив типа A=Set<Object> суём туда кучу всякого, а потом вызываем через ((IMyinterface)A).myvoid() |
|||
93
Asmody
26.12.19
✎
12:06
|
Есть "пустой" интерфейс, которому удовлетворяет всё. Ещё есть рефлексия. Но это настолько явный способ выстрелить себе в ногу, что ты уже должен четко понимать, что ты делаешь.
|
|||
94
Garikk
26.12.19
✎
12:07
|
(92) *во кстати, этож пример утиной типизации в яве
|
|||
95
pechkin
26.12.19
✎
12:07
|
(92) ну на такое явно компилятор нигде не ругнется
|
|||
96
Garikk
26.12.19
✎
12:08
|
ну да...на самом деле действительно implements не особо нужен, хотя наглядность падает
|
|||
97
pechkin
26.12.19
✎
12:10
|
как в 1с практически
|
|||
98
Integrator
26.12.19
✎
12:37
|
У неявного implements есть большой плюс - если у тебя уже есть какие-то объекты из сторонней библиотеки, и понадобилось вдруг добавить свои, но так что бы и свои, и чужие, реализовывали общий интерфейс - просто описываешь нужный интерфейс, и все, не нужно в чужой код лезть, что бы туда явный implements добавить.
|
|||
99
Asmody
26.12.19
✎
12:42
|
(97) В 1С вообще не так. В 1С навернется в рантайме, если ты где-то там к чему-то несуществующему обратился.
|
|||
100
vicof
26.12.19
✎
13:09
|
(100)
|
Форум | Правила | Описание | Объявления | Секции | Поиск | Книга знаний | Вики-миста |