Go библиотека unsafe
С помощью пакета
Есть определенные риски использования unsafe pointers, один из них это то что библиотека не защищена гарантией обратной совместимости Go 1 и будущее программ Go. To есть код зависящий от
Примеры использования:
Любой указатель Go может быть преобразован в
Ещё пример:
@cto_tech
С помощью пакета
unsafe можно делать множество интересных хаков без оглядки на систему типов Go. Он дает доступ к низкоуровневому АПИ почти как в C. Но использование unsafe - это легкий способ выстрелить себе в ногу, поэтому нужно соблюдать определенные правила. При написании такого кода очень легко совершить ошибку.Есть определенные риски использования unsafe pointers, один из них это то что библиотека не защищена гарантией обратной совместимости Go 1 и будущее программ Go. To есть код зависящий от
unsafe pointers может сломаться в будущих версиях Go.Примеры использования:
Любой указатель Go может быть преобразован в
unsafe.Pointer:import (
"fmt"
"unsafe"
)
type TestStruct struct {
b1 byte
b2 byte
i int16
}
func main() {
testStruct := TestStruct{
b1: 2,
b2: 4,
i: 261,
}
type arrayType [4]byte
fmt.Println("size = ", unsafe.Sizeof(testStruct))
// size = 4
up := unsafe.Pointer(&testStruct)
testByteArray := *(*arrayType)(up)
fmt.Println("отображаем массив байт = ",
testByteArray,
)
// отображаем массив байт = [2 4 5 1]
}
Ещё пример:
func main() {
s := "foo"
b := []byte(s)
x := struct{ a int, b bool}{1, true}
sp := unsafe.Pointer(&s)
bp := unsafe.Pointer(&b)
xp := unsafe.Pointer(&x)
println(sp, bp, xp)
}
// адреса будут отличаться
// 0x14000052710 0x14000052720
// 0x140000526f8@cto_tech
Побитовые операции в Go
Побитовые операции выполняются над отдельными разрядами чисел в бинарном представлении. Например, число 5 в двоичной системе имеет три разряда: 101, а число восемь - четыре разряда: 1000.
Операции сдвига:
<<
>>
Сдвигает битовое представление числа, например:
Поразрядные операции:
& - операция И или поразрядное умножение;
| - операция ИЛИ или поразрядное сложение;
^ - поразрядное исключающее ИЛИ. Возвращает 1, если только один из соответствующих разрядов обоих чисел равен 1;
&^ - сброс бита (И НЕ);
Примеры:
@cto_tech
Побитовые операции выполняются над отдельными разрядами чисел в бинарном представлении. Например, число 5 в двоичной системе имеет три разряда: 101, а число восемь - четыре разряда: 1000.
Операции сдвига:
<<
>>
Сдвигает битовое представление числа, например:
var b int = 2 << 2; // 2 это 10 на два разрядов влево = 1000 или 8
var c int = 16 >> 3; // 16 это 10000 на три разряда вправо = 100 или 2
Поразрядные операции:
& - операция И или поразрядное умножение;
| - операция ИЛИ или поразрядное сложение;
^ - поразрядное исключающее ИЛИ. Возвращает 1, если только один из соответствующих разрядов обоих чисел равен 1;
&^ - сброс бита (И НЕ);
Примеры:
func main() {
var a int = 5 | 2; // 101 | 010 = 111 или 7
var b int = 6 & 2; // 110 & 010 = 10 или 2
var c int = 5 ^ 2; // 101 ^ 010 = 111 или 7
var d int = 5 &^ 6; // 101 &^ 110 = 001 или 1
}@cto_tech
1
Паттерны проектирования
Структурный паттерн Адаптер
Adapter — структурный шаблон проектирования, предназначенный для организации использования функций объекта, недоступного для модификации, через специально созданный интерфейс. Например реализация определенного интерфейса для класса или структуры.
Рассмотрим пример на go:
Далее мы адаптируем функционал под наши нужды:
@cto_tech
Структурный паттерн Адаптер
Adapter — структурный шаблон проектирования, предназначенный для организации использования функций объекта, недоступного для модификации, через специально созданный интерфейс. Например реализация определенного интерфейса для класса или структуры.
Рассмотрим пример на go:
// интерфейс структуры для адаптера
type Target interface {
Operation()
}
// адаптируемая структура
type AdapteeStruct struct {
some int
}
// Метод адаптируемой структуры, который нужно вызвать где-то
func (adaptee *AdapteeStruct) AdaptedOperation() {
fmt.Println("I am AdaptedOperation()")
}
Далее мы адаптируем функционал под наши нужды:
// Структура конкретного адаптера
type ConcreteAdapter struct{
*AdapteeStruct
}
// реализация метода интерфейса, реализующего вызов адаптируемого класса
func (adapter *ConcreteAdapter) Operation() {
adapter.AdaptedOperation()
}
// основной метод для демонстрации
func main() {
fmt.Println("\nAdapter demo:\n")
adapter := NewAdapter(&Adaptee{})
adapter.Operation()
}
@cto_tech
Структуры Go
Структура (struct) используется для создания коллекции элементов разных типов данных в одной переменной.
В отличие от массивов, которые используются для хранения нескольких значений одного и того же типа данных в одной переменной, структуры используются для хранения нескольких значений разных типов данных в одной переменной.
Структура может быть полезна для группировки данных для создания записей.
В Go любая более-менее сложная сущность так или иначе представляет собой структуру.
@cto_tech
Структура (struct) используется для создания коллекции элементов разных типов данных в одной переменной.
В отличие от массивов, которые используются для хранения нескольких значений одного и того же типа данных в одной переменной, структуры используются для хранения нескольких значений разных типов данных в одной переменной.
Структура может быть полезна для группировки данных для создания записей.
В Go любая более-менее сложная сущность так или иначе представляет собой структуру.
type some struct {
a int
b string
c bool
}
func main() {
s := some{1, "hello", true}
println(s.a, s.b, s.c)
// 1 hello true
}@cto_tech
Паттерн проектирования Мост
Мост (Bridge) — структурный шаблон проектирования, используемый в проектировании программного обеспечения чтобы «разделять абстракцию и реализацию так, чтобы они могли изменяться независимо». Шаблон мост использует инкапсуляцию, агрегирование и может использовать наследование для того, чтобы разделить ответственность между классами.
Мост (Bridge) — структурный шаблон проектирования, используемый в проектировании программного обеспечения чтобы «разделять абстракцию и реализацию так, чтобы они могли изменяться независимо». Шаблон мост использует инкапсуляцию, агрегирование и может использовать наследование для того, чтобы разделить ответственность между классами.
Среда выполнения Go и его конкурентность абсолютно феноменальны. Сложно представить возвращение к JS у которого среда выполняния Node/deno.
Полностью поддерживаю⚡️
Полностью поддерживаю
Please open Telegram to view this post
VIEW IN TELEGRAM
Паттерн Мост на typescript
Предназначение
Данный шаблон применяется, когда есть потребность реализовать одинаковые формат API, для разных сервисов, которые выполняют одну и ту же функциональность.
Суть паттерна
Создать общий интерфейс для каждого из класса сервиса, где описать все методы API. Реализовать каждый класс, такого сервиса через имплементацию этого интерфейса, после чего реализовать класс, в конструктор которого передается этот же интерфейс и в общие методы API группируются в один метод, при этом этот метод в себе ссылается на this аргумента реализующий этот интерфейс.
Пример реализации
Приложение, по отправке сообщений. При этом оно должно реализовывать функциональность мгновенных и отложенных сообщений, а так же реализовывать эту функциональность для разного типа мессенджеров.
interface IProvider {
sendMessage(messsage: string): void;
connect<T>(config: T): void;
disconnect(): void;
}
class TelegramProvider implements IProvider {
connect<T>(config: T): void {
console.log(config)
}
disconnect(): void {
console.log(`Disconnected TG`)
}
sendMessage(messsage: string): void {
console.log(messsage)
}
}
class WhatAppPRovider implements IProvider {
connect<T>(config: T): void {
console.log(config)
}
disconnect(): void {
console.log(`Disconnected WA`)
}
sendMessage(messsage: string): void {
console.log(messsage)
}
}
class NotificationSender {
constructor (private provider: IProvider) {}
send() {
this.provider.connect('connect')
this.provider.sendMessage('message')
this.provider.disconnect()
}
}
class DelayNotificationSender extends NotificationSender {
constructor(provider: IProvider) {
super(provider)
}
sendDeployed() {}
}
const sender = new NotificationSender(new TelegramProvider())
sender.send();
const sender2 = new NotificationSender(new WhatAppPRovider())
sender2.send();Предназначение
Данный шаблон применяется, когда есть потребность реализовать одинаковые формат API, для разных сервисов, которые выполняют одну и ту же функциональность.
Суть паттерна
Создать общий интерфейс для каждого из класса сервиса, где описать все методы API. Реализовать каждый класс, такого сервиса через имплементацию этого интерфейса, после чего реализовать класс, в конструктор которого передается этот же интерфейс и в общие методы API группируются в один метод, при этом этот метод в себе ссылается на this аргумента реализующий этот интерфейс.
Пример реализации
Приложение, по отправке сообщений. При этом оно должно реализовывать функциональность мгновенных и отложенных сообщений, а так же реализовывать эту функциональность для разного типа мессенджеров.
Паттерн проектирования Компоновщик (Composite)
#GOF
#structural_pattern
Компоновщик (Composite pattern) — структурный шаблон проектирования, объединяющий объекты в древовидную структуру для представления иерархии от частного к целому. Компоновщик позволяет клиентам обращаться к отдельным объектам и к группам объектов одинаково.
#GOF
#structural_pattern
Компоновщик (Composite pattern) — структурный шаблон проектирования, объединяющий объекты в древовидную структуру для представления иерархии от частного к целому. Компоновщик позволяет клиентам обращаться к отдельным объектам и к группам объектов одинаково.