package main
import (
"fmt"
)
type MyError struct {
Message string
}
func (e MyError) Error() string {
return e.Message
}
func main() {
// Возвращаем из функции нашу кастомную ошибку, но в виде интерфейса error
err := foo()
if err == nil {
fmt.Println("Нет ошибки")
// И теперь тут приводим error к нашему типу MyError и проверяем
} else if myErr, ok := err.(MyError); ok {
fmt.Printf("Ура! Нужный нам тип ошибки: %v\n", myErr.Message)
} else {
fmt.Println("Какой-то другой тип ошибки:", err)
}
// Проверка одной из "подстав" Go
err = bad()
if err != nil {
fmt.Println("Упс... Как так... Не nil...")
} else {
fmt.Println("Должно вывестись это, но не выводится...")
}
err = good()
if err != nil {
fmt.Println("Это не должно выводиться, всё верно.")
} else {
fmt.Println("Ошибки нет, всё верно.")
}
}
func foo() error {
err := MyError{"Ой! Ошибка MyError!"}
// err := fmt.Errorf("Ой! Обычная ошибка!")
// var err error = nil
return err
}
func bad() error {
var p *MyError = nil // Вроде же nil, но не работает....
// p = &MyError{"Ой!"} // Пробуем создать ошибку, и всё работает.
if p == nil {
fmt.Println("Ну nil же-ж... Должно же-ж работать", p)
}
return p
}
func good() error {
// return MyError{"Ой!"}
// Буквально пишем "nil", никаких указателей, которые равны nil, это прямой выстрел в ногу
return nil
}
#[ApiResource(
operations: [
new Get(), // item
new Put(), // item
new Patch(), // item
new Delete(), // item
new GetCollection(), // collection
new Post() // collection
],
)]
<?php
class Node
{
protected function func1() {
print "NODE PARENT; ";
}
}
class NodeA extends Node
{
public function FUNC2() {
print "NODE A; ";
}
// Используем метод родителя внутри этого класса
public function func1Overrided() {
print "From parent: " . parent::func1();
}
// Переопределяем метод так, чтобы его нельзя было использовать
protected function func1() {
throw new \Exception("Нельзя вызывать этот метод из NodeB");
}
}
class NodeB extends Node
{
// Функция инициализации
public function onInit(NodeA $a): void
{
// Сделал так, чтобы не мокать api )
(function (?NodeA $a) {
$a->FUNC2(); // Метод успешно вызывется так как он public
$a->func1(); // Метод теперь кидает исключение, использовать не получится
})($a);
}
}
$nodeA = new NodeA;
$nodeA->func1Overrided(); // Работает вызов метода funс1 из родителя
$nodeB = new NodeB;
$nodeB->onInit($nodeA); // Выдаёт ошибку, нельзя использовать метод func1 из класса NodeB
<?php
// Делаем общий трейт для всех классов
trait Func1 {
private function func1() {
print "FUNC1; ";
}
}
class Node
{
// Включаем трейт
use Func1;
}
class NodeA extends Node
{
// Включаем трейт
use Func1;
public function FUNC2() {
print "FUNC 2 NODEA; ";
}
}
class NodeB extends Node
{
// Включаем трейт
use Func1;
// Функция инициализации
public function onInit(NodeA $a): void
{
// Добавить зависимость
(function (?NodeA $a) {
$a->FUNC2(); // Метод успешно вызывется так как он public
$a->func1(); // Метод использовать не получится, т.к. он private
})($a);
}
}
$nodeA = new NodeA;
$nodeB = new NodeB;
$nodeB->onInit($nodeA); // Выдаёт ошибку, нельзя использовать метод func1 из класса NodeB
В services.yaml вставил
App\Entity\Page:
autowire: true
<?php
namespace App\Controller;
use App\Entity\Page;
use App\Repository\PageRepository;
use Symfony\Bridge\Doctrine\Attribute\MapEntity;
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\Routing\Attribute\Route;
class PageController extends AbstractController
{
// ...
#[Route('/{slug}', name: 'show-page')]
public function show(
#[MapEntity(mapping: ['slug' => 'slug'])] Page $page
): Response
{
return $this->render('/page/show.html.twig', [
'slug' => $page->getSlug(),
'page' => $page,
]);
}
}
<input type="submit" value="save" name="loginForm">
if (isset($_POST['loginForm'])){
// Код
}
package db
import "fmt"
// Стуктура базы данных. Здесь нам даже и не нужно объявлять никаких интерфейсов
type Service struct {
// ...
}
func NewDbService() (*Service, error) {
return &Service{}, nil
}
func (d *Service) CreateUser(username string, email string) {
fmt.Println(fmt.Sprintf("user %s with email %s is created", username, email))
}
func (d *Service) CreateProduct(name string) {
fmt.Println(fmt.Sprintf("product %s is created", name))
}
package user
// Тот самый интерфейс, который нам позволяет выбрать из структуры базы данных
// только нужные нам здесь методы
type dbUser interface {
CreateUser(username string, email string)
}
type Service struct {
db dbUser
// ...
}
func NewService(db dbUser) (*Service, error) {
return &Service{db}, nil
}
func (c *Service) New(username string, email string) {
c.db.CreateUser(username, email)
}
package product
// Тот самый интерфейс, который нам позволяет выбрать из структуры базы данных
// только нужные нам здесь методы
type dbProduct interface {
CreateProduct(name string)
}
type Service struct {
db dbProduct
// ...
}
func NewService(db dbProduct) (*Service, error) {
return &Service{db}, nil
}
func (p *Service) New(name string) {
p.db.CreateProduct(name)
}
package main
import (
"test2/db"
"test2/product"
"test2/user"
)
func main() {
// Инициализируем базу данных
dbService, _ := db.NewDbService()
// Структура базы данных реализует интерфейс dbProduct, инжектим её
productService, _ := product.NewService(dbService)
// Структура базы данных реализует интерфейс dbUser, инжектим её
userService, _ := user.NewService(dbService)
// Пользуемся на здоровье...
userService.New("user1", "uswr1@example.com")
productService.New("product1")
}
"ConnectionStrings": {
"DefaultConnection": "User ID=postgres;Password=postgres;Host=db;Port=5432;Database=example;"
}
const arr = [
{src: 'some-path-1', video: 'some-path-1'},
{src: 'some-path-2', video: 'some-path-2'},
{src: 'some-path', video: null},
];
const result = [];
for (let i = 0; i < arr.length; i++) {
if (arr[i]?.video) {
result.push({ src_video: arr[i].video });
}
result.push(arr[i]);
}
console.log(result);