Имя: Пароль:
IT
 
Небольшой вопрос по 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)
2 + 2 = 3.9999999999999999999999999999999...